maxrecursion에 대한 시스템 전체 기본값 변경


12

시스템 전체 기본값을 어떻게 변경 MAXRECURSION합니까?

기본적으로 100이지만 1000과 같이 늘려야합니다.

쿼리를 가져 와서 실행하는 프로그램을 사용하고 있기 때문에 쿼리 힌트를 사용할 수 없으며 불행히도이 제한을 극복 할 수 없습니다.

그러나 서버 인스턴스에 대한 관리자 권한이 있습니다. 서버 패싯에서 찔 렀지 만 쿼리 옵션이나 재귀와 관련된 것은 없습니다. 시스템 전체 기본값을 업데이트 할 수있는 위치 있어야 한다고 가정 합니다.

어떤 아이디어?


3
방금 뷰와 함수에만 100이 제한되어 있고 저장 프로 시저를 사용하고 로컬에서 재정의 할 수 있음을 이해하고 싶습니까? 함수를 사용해야 할 필요가 있습니까? 재귀가 상당히 비효율적이므로 계층 구조를 한 번만 걷고 출력을 테이블에 저장하는 것이 좋습니다. 그런 다음 해당 테이블을 참조하는 함수를 작성할 수 있습니다. 어떻게 생각해?
wBob

답변:


10

쿼리가 공통된 형태 인 경우 하나 이상의 계획 지침을 사용하여 필요한 최대 재귀 힌트를 추가 할 수 있습니다.

그것들을 올바르게 얻는 데 어려움이있을 수 있습니다. 질문에 특정 검색어 세부 정보를 추가하면 문제를 해결할 수 있습니다. 일반적으로 실제로 서버에 도달하는 SQL을 추적하거나 내장 프로 시저 sys.sp_get_query_template를 사용하여 매개 변수화 된 양식을 얻은 다음 TEMPLATE 및 / 또는 OBJECT / SQL 계획 안내서를 작성하십시오.

자세한 내용은 설명서를 참조하십시오.

응용 프로그램 코드가 변경 될 때마다 그리고 SQL Server가 패치되거나 업그레이드 될 때마다 계획 지침을 다시 확인해야합니다. 이것은 정상적인 테스트주기의 일부 여야합니다.

안내문 이 임시 테이블을 참조하는 경우 sys.fn_validate_plan_guide를 사용한 계획 안내서 유효성 검증 이 실패를 잘못보고 할 수 있습니다. 이 질문을보십시오 :

fn_validate_plan_guide를 사용한 계획 가이드 유효성 검사는 오 탐지

계획 가이드 성공적인계획 설명서 실패 프로파일 및 확장 이벤트 클래스는 계획 지침의 응용 프로그램을 모니터링하는 데 사용할 수 있습니다.

Steve Kass의 뷰 및 UDF에 대해 MAXRECURSION 허용 값 100 이외의 값 을 구현 하기 전에 Connect가 종료 되었습니다. 지금 Microsoft에 맡기려면 SQL Server 도움말 및 피드백 의 옵션을 참조하십시오 .


이것은 실망스럽고 대신 문서의 토끼 구멍에 묻어 버리는 질문에 대답하지 않습니다. EF Core (일반적인 ORM)는 원시 SQL 문을 주더라도 부모 선택에서 EF Core를 사용하는 사람이라면 누구나이 문제가 있다고 래핑합니다. 귀하의 솔루션은 "질의를 계획"입니다.
전쟁

@War이 세부적인 질문에 제가 제공 할 수있는 가장 좋은 답변입니다. 최대 재귀 힌트 를 추가하는 유일한 방법 은 계획 쿼리라는 SQL Server를 사용하는 것입니다.이 쿼리는 "쿼리 계획"과 관련이 없습니다. 당신이 당신의 자신의 특정 질문이있는 경우, 최소한의 재현 가능한 예 와 별도로 질문하십시오 .
Paul White 9

9

함수 (절대로 암시 된대로 ETL 도구의 제한 사항)를 사용해야하는 OPTION경우 다중 명령문 테이블 값 함수의 일부로 다음과 같이 지정할 수 있습니다 .

CREATE FUNCTION dbo.udf_MyFunction ( @StartID INT ) 
RETURNS @tv TABLE
(
id INT
)
AS
BEGIN

    WITH Episodes( xlevel, PersonID, EventID, EpisodeID, StartDT, EndDT ) AS (
    -- Anchor case - the first EventID for each person.
    SELECT 1 AS xlevel, PersonID, EventID, @StartID, StartDT, EndDT 
    FROM dbo.EventTable
    WHERE EventID = @StartID

    UNION ALL

    SELECT xlevel + 1, et.PersonID, et.EventID, c.EventID + 1, et.StartDT, et.EndDT
    FROM Episodes c
        INNER JOIN dbo.EventTable et ON c.PersonID = et.PersonID
            AND et.EventID = c.EventID + 1
    --WHERE c.EventID <= (@StartID + 99)
    )
    INSERT INTO @tv
    SELECT PersonID
    FROM Episodes
    OPTION ( MAXRECURSION 1000 )

    RETURN

END
GO

ETL 도구가 제안하는 것처럼보기에 싸여있을 때도 도움이되었습니다. 이 시스템 전체를 변경할 수있는 방법은 없지만 재귀가 비효율적 일 수 있으므로 이것이 좋은 방법 일 것입니다. OPTION예제와 같이 인라인 테이블 반환 함수의 본문 내 에서을 사용하여 쿼리 힌트를 지정할 수 없습니다 .

에피소드를 수신하고 출력을 관계형 테이블에 저장할 때 계층 구조를 한 번만 걸도록 프로세스를 변경하십시오. 저장 프로 시저를 사용 하여이 작업을 수행 할 수 있으므로이 제한이 적용되지 않습니다.

또한 코드에 버그가 있다고 생각합니다. CTE가 personId에 가입하고 eventId에 반복되는 경우 eventId 101은 중복으로 생각한 것보다 두 번 나타납니다. 아마도 귀하의 코드를 잘못 해석했을 것입니다. 어떻게 생각하는지 알려주십시오.

HTH


"OPTIONS"매개 변수를 명령문 레벨에서 적용해야하고 해당 명령문이 함수에 대한 호출이므로 예외가 리턴됩니다.
전쟁

0

나는 이 주제 에서 영감을 얻었습니다 .

문제를 해결하기 위해 내가 한 일이 있습니다.

CREATE FUNCTION MySchema.udf_MyFunction(@StartID INT) 
RETURNS TABLE 
AS RETURN
WITH
Episodes(PersonID, EventID, EpisodeID, StartDT, EndDT) AS (
  -- Anchor case - the first EventID for each person.
  SELECT PersonID, EventID, @StartID, StartDT, EndDT 
  FROM MySchema.EventTable
  WHERE EventID = @StartID
UNION ALL
  SELECT
    ...
  WHERE
    EventID <= (@StartID + 99)
)
SELECT * FROM Episodes

그런 다음이 기능을 다음과 같이 호출합니다.

WITH
Episodes AS (
  SELECT * FROM MySchema.udf_MyFunction(1)
UNION ALL
  SELECT * FROM MySchema.udf_MyFunction(101)
UNION ALL
  SELECT * FROM MySchema.udf_MyFunction(201)
-- ...
UNION ALL
  SELECT * FROM MySchema.udf_MyFunction(901)
)
SELECT * FROM Episodes

이런 식으로 CTE 로직을 반복 할 필요가 없으며 성능 측면에서 추가 비용을 지불하지 않습니다. 이런 식으로해야한다는 것은 성가신 일이지만 나는 함께 살 수 있습니다.


3
이것이 재귀 문제를 어떻게 해결하는지 모르겠습니다. 함수의 호출은 재귀 적이 지 않습니다.
ypercubeᵀᴹ

@ ypercubeᵀᴹ-CTE의 재귀 비트는 내가 줄임표가있는 곳으로 간다. 내 특정 재귀 논리는 실제로 문제와 관련이 없지만 CTE는 실제로 재귀 적이라고 가정 할 수있다. where줄임표 뒤에 나오는 절은 함수 매개 변수를 제약 조건으로 사용하여 너무 많은 재귀가 발생하지 않도록합니다. 그래도 CTE 정의 뒤에 진술이 있어야한다고 생각합니다 . 추가하겠습니다.
carl.anderson

3
CTE가 재귀 적이라는 것을 잘 알고 있습니다. 문제는 호출 (함수 호출)이 재귀 적이 지 않다는 것 입니다. 예를 들어 EventID=1(및 101,201, ... 901) 로 시작점 (행)이있는 함수를 호출합니다 . 그러나 원래 쿼리 (MAXRECURSION = 100000000으로 실행 된 경우)는 EventID=101(및 201, .., 901)을 가진 행을 방문하지 않을 수 있습니다 . 따라서 두 쿼리 (원본 및 솔루션)는 다른 결과를 반환 할 수 있습니다 (첫 번째에는 101, 두 번째에는 예). 또는 101 단계를 방문하지만 100 단계 이전에 솔루션에 결과에 행이 두 번 포함될 수 있습니다 (다시 다릅니다)
ypercubeᵀᴹ

2
물론 데이터가 순차적 인 EventID 값 (1,2,, 3 ..., 99,100,101, ..)으로 연결되지 않는 한. 이 경우 재귀 CTE가 전혀 필요하지 않습니다.
ypercubeᵀᴹ

주어진 DMS 경로에서 나무를 행 집합으로 가져 오는 것과 같은 미지의 깊이 문제를 어떻게 해결합니까?
전쟁
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.