SQL Server는 다중 문 테이블 반환 함수의 결과를 캐시합니까?


답변:


23

다중 문 테이블 반환 함수 (msTVF)의 결과는 문 (또는 연결)에서 캐시되거나 재사용 되지 않지만 msTVF 결과가 같은 문 에서 재사용 될 수있는 몇 가지 방법이 있습니다 . 그 정도로 msTVF가 호출 될 때마다 다시 채워지는 것은 아닙니다.

msTVF 예

이 (고의로 비효율적 인) msTVF는 각 행에 타임 스탬프와 함께 지정된 범위의 정수를 반환합니다.

IF OBJECT_ID(N'dbo.IntegerRange', 'TF') IS NOT NULL
    DROP FUNCTION dbo.IntegerRange;
GO
CREATE FUNCTION dbo.IntegerRange (@From integer, @To integer)
RETURNS @T table 
(
    n integer PRIMARY KEY, 
    ts datetime DEFAULT CURRENT_TIMESTAMP
)
WITH SCHEMABINDING
AS
BEGIN
    WHILE @From <= @To
    BEGIN
        INSERT @T (n)
        VALUES (@From);

        SET @From = @From + 1;
    END;
    RETURN;
END;

정적 테이블 변수

함수 호출에 대한 모든 매개 변수가 상수 (또는 런타임 상수) 인 경우 실행 계획은 테이블 변수 결과를 한 번 채 웁니다. 계획의 나머지 부분은 테이블 변수에 여러 번 액세스 할 수 있습니다. 테이블 변수의 정적 특성은 실행 계획에서 인식 할 수 있습니다. 예를 들면 다음과 같습니다.

SELECT
    IR.n,
    IR.ts 
FROM dbo.IntegerRange(1, 5) AS IR
ORDER BY
    IR.n;

다음과 유사한 결과를 반환합니다.

간단한 결과

실행 계획은 다음과 같습니다.

간단한 실행 계획

Sequence 연산자는 먼저 Table Valued Function 연산자를 호출하여 테이블 변수를 채 웁니다 (이 연산자는 행을 반환하지 않습니다). 그런 다음 시퀀스는 두 번째 입력을 호출하여 테이블 변수의 내용을 반환합니다 (이 경우 클러스터형 인덱스 스캔 사용).

계획이 '정적'테이블 변수 결과를 사용하고 있다는 사실은 시퀀스 아래의 테이블 값 함수 연산자입니다. 테이블 변수는 계획의 나머지가 진행되기 전에 한 번 완전히 채워 져야합니다.

여러 번의 액세스

테이블 변수 결과가 두 번 이상 액세스됨을 표시하기 위해 행 번호가 1에서 5까지 인 두 번째 테이블을 사용합니다.

IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
    DROP TABLE dbo.T;

CREATE TABLE dbo.T (i integer NOT NULL);

INSERT dbo.T (i) 
VALUES (1), (2), (3), (4), (5);

그리고이 테이블을 함수에 조인하는 새로운 쿼리 (이것은으로도 쓰일 수 있습니다 APPLY) :

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
JOIN dbo.IntegerRange(1, 5) AS IR
    ON IR.n = T.i;

결과는 다음과 같습니다.

가입 결과

실행 계획 :

플랜 가입

이전과 마찬가지로 시퀀스는 테이블 변수 msTVF 결과를 먼저 채 웁니다. 다음으로 중첩 루프를 사용하여 테이블의 각 행을 TmsTVF 결과의 행 으로 조인합니다 . 함수 정의에 테이블 변수에 유용한 인덱스가 포함되어 있으므로 인덱스 탐색을 사용할 수 있습니다.

요점은 msTVF에 대한 매개 변수가 상수 (변수 및 매개 변수 포함)이거나 실행 엔진에 의한 명령문에 대한 런타임 상수로 처리 될 때 계획에 msTVF 테이블 변수 결과에 대해 두 개의 별도 연산자가있는 것입니다. 표; 다른 하나는 결과에 액세스하여 테이블에 여러 번 액세스하고 함수 정의에 선언 된 인덱스를 사용할 수 있습니다.

상관 된 매개 변수 및 불변의 매개 변수

상관 된 매개 변수 (외부 참조) 또는 비 일관적인 함수 매개 변수를 사용할 때의 차이점을 강조 T하기 위해 함수가 훨씬 더 많은 작업을 수행 할 수 있도록 테이블의 내용을 변경합니다 .

TRUNCATE TABLE dbo.T;

INSERT dbo.T (i) 
VALUES (50001), (50002), (50003), (50004), (50005);

다음 수정 된 쿼리는 이제 T함수 매개 변수 중 하나 에서 테이블 에 대한 외부 참조를 사용합니다 .

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
WHERE IR.n = T.i;

이 쿼리는 다음과 같은 결과를 반환하는 데 약 8 초가 걸립니다 .

상관 된 결과

열의 행 간 시간 차이를 확인하십시오 ts. 이 WHERE절은 합리적인 크기의 출력에 대한 최종 결과를 제한하지만 비효율적 인 함수는 테이블 변수를 50,000-odd 행으로 채우는 데 여전히 시간이 걸립니다 ( ifrom table 의 상관 값에 따라 다름 T).

실행 계획은 다음과 같습니다.

상관 된 실행 계획

Sequence 연산자가 없다는 것을 알 수 있습니다. 이제 테이블 변수를 채우고 중첩 루프 조인의 각 반복 에서 해당 행 반환하는 단일 테이블 반환 함수 연산자가 있습니다.

테이블 T에 5 개의 행만 있으면 Table Valued Function 연산자가 5 번 실행됩니다. 첫 번째 반복에서 50,001 개의 행을 생성하고 두 번째 반복에서 50,002 개의 행을 생성합니다. 테이블 변수는 반복 사이에 '제거 (잘려)'되므로 5 개의 호출 각각은 전체 모집단입니다. 그렇기 때문에 속도가 느리고 각 행이 결과에 표시되는 데 거의 같은 시간이 걸립니다.

사이드 노트 :

당연히, 위의 시나리오는 msTVF가 각 반복에서 많은 행을 채울 때 성능이 얼마나 저하 될 수 있는지를 보여주기 위해 의도적으로 고안되었습니다.

합리적인 위의 코드의 구현은 설정합니다 모두 에 msTVF 매개 변수를 i하고, 중복 제거 WHERE절을. 테이블 변수는 반복 할 때마다 잘리고 다시 채워지지만 매번 한 행 씩만 채워집니다.

또한 이전 단계에서 최소값과 최대 i값을 가져와 T변수에 저장할 수 있습니다. 상관 된 매개 변수 대신 변수를 사용하여 함수를 호출하면 앞에서 언급 한대로 '정적'테이블 변수 패턴을 사용할 수 있습니다.

변경되지 않은 상관 매개 변수 캐싱

시퀀스 정적 패턴을 사용할 수없는 원래 질문을 다시 한 번 리턴하기 위해 SQL Server는 중첩 루프 조인의 이전 반복 이후에 상관 된 매개 변수가 변경되지 않은 경우 msTVF 테이블 변수를 자르고 다시 채우는 것을 피할 수 있습니다 .

이를 입증하기 위해 내용을 T5 개의 동일한 i 값으로 대체 합니다.

TRUNCATE TABLE dbo.T;

INSERT dbo.T (i) 
VALUES (50005), (50005), (50005), (50005), (50005);

상관 된 매개 변수가있는 쿼리 :

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
WHERE IR.n = T.i;

이번에는 약 1.5 초 후에 결과가 나타납니다 .

동일한 행 결과

각 행에서 동일한 타임 스탬프에 유의하십시오. 테이블 변수의 캐시 된 결과는 상관 된 값 i이 변경되지 않은 후속 반복에 재사용됩니다 . 매번 50,005 개의 행을 삽입하는 것보다 결과를 재사용하는 것이 훨씬 빠릅니다.

실행 계획은 이전과 매우 유사합니다.

동일한 행 계획

주요 차이점은 Table Valued Function 연산자 의 Actual RebindsActual Rewinds 속성에 있습니다.

연산자 속성

상관 된 매개 변수가 변경되지 않으면 SQL Server는 테이블 변수에서 현재 결과를 재생 (되감기) 할 수 있습니다. 상관 관계가 변경되면 SQL Server는 테이블 변수를 잘라내어 다시 채워야합니다 (리 바인드). 하나의 리 바인드는 첫 번째 반복에서 발생합니다. 값 T.i이 변경되지 않기 때문에 4 개의 후속 반복은 모두 되감기 됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.