테이블 변수를 사용하여 옵티마이 저가 인덱스 검색을 사용하지 못하고 북마크 조회와 인덱스 스캔을 사용하지 못하는 이유를 이해하려고합니다.
테이블 채우기 :
CREATE TABLE dbo.Test
(
RowKey INT NOT NULL PRIMARY KEY,
SecondColumn CHAR(1) NOT NULL DEFAULT 'x',
ForeignKey INT NOT NULL
)
INSERT dbo.Test
(
RowKey,
ForeignKey
)
SELECT TOP 1000000
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
ABS(CHECKSUM(NEWID()) % 10)
FROM sys.all_objects s1
CROSS JOIN sys.all_objects s2
CREATE INDEX ix_Test_1 ON dbo.Test (ForeignKey)
단일 레코드로 테이블 변수를 채우고 외래 키 열을 검색하여 기본 키와 두 번째 열을 찾아보십시오.
DECLARE @Keys TABLE (RowKey INT NOT NULL)
INSERT @Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
@Keys k
ON
t.ForeignKey = k.RowKey
실행 계획은 다음과 같습니다.
이제 임시 테이블을 대신 사용하는 동일한 쿼리 :
CREATE TABLE #Keys (RowKey INT NOT NULL)
INSERT #Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
#Keys k
ON
t.ForeignKey = k.RowKey
이 쿼리 계획은 찾기 및 책갈피 조회를 사용합니다.
옵티마이 저가 테이블 변수가 아닌 임시 테이블을 사용하여 책갈피 조회를 원하는 이유는 무엇입니까?
이 예제에서 테이블 변수는 스토어드 프로 시저에서 사용자 정의 테이블 유형을 통해 오는 데이터를 나타내는 데 사용됩니다.
외래 키 값이 수십만 번 발생하면 인덱스 탐색이 적절하지 않을 수 있음을 알고 있습니다. 이 경우 스캔이 더 나은 선택 일 수 있습니다. 내가 만든 시나리오의 경우 값이 10 인 행이 없었습니다. 여전히 동작이 흥미롭고 그 이유가 있는지 알고 싶습니다.
추가해도 OPTION (RECOMPILE)
동작이 변경되지 않았습니다. UDDT에는 기본 키가 있습니다.
@@VERSION
Server 2008 R2 (SP2)-10.50.4042.0 (X64) (빌드 7601 : 서비스 팩 1) (하이퍼 바이저)