예상치 못한 것으로 설명되는 쿼리 성능 문제를 재현 할 수있었습니다. 내부에 중점을 둔 답변을 찾고 있습니다.
내 컴퓨터에서 다음 쿼리는 클러스터형 인덱스 스캔을 수행하며 약 6.8 초의 CPU 시간이 걸립니다.
SELECT ID1, ID2
FROM two_col_key_test WITH (FORCESCAN)
WHERE ID1 NOT IN
(
N'1', N'2',N'3', N'4', N'5',
N'6', N'7', N'8', N'9', N'10',
N'11', N'12',N'13', N'14', N'15',
N'16', N'17', N'18', N'19', N'20'
)
AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))
ORDER BY ID1, ID2 OFFSET 12000000 ROWS FETCH FIRST 1 ROW ONLY
OPTION (MAXDOP 1);
다음 쿼리는 클러스터 된 인덱스 탐색을 수행하지만 (차이 만이 FORCESCAN
힌트를 제거하는 것임) 약 18.2 초의 CPU 시간이 걸립니다.
SELECT ID1, ID2
FROM two_col_key_test
WHERE ID1 NOT IN
(
N'1', N'2',N'3', N'4', N'5',
N'6', N'7', N'8', N'9', N'10',
N'11', N'12',N'13', N'14', N'15',
N'16', N'17', N'18', N'19', N'20'
)
AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))
ORDER BY ID1, ID2 OFFSET 12000000 ROWS FETCH FIRST 1 ROW ONLY
OPTION (MAXDOP 1);
쿼리 계획은 매우 비슷합니다. 두 쿼리 모두 클러스터 된 인덱스에서 120000001 개의 행을 읽습니다.
SQL Server 2017 CU 10을 사용하고 있습니다. two_col_key_test
테이블 .
drop table if exists dbo.two_col_key_test;
CREATE TABLE dbo.two_col_key_test (
ID1 NVARCHAR(50) NOT NULL,
ID2 NVARCHAR(50) NOT NULL,
FILLER NVARCHAR(50),
PRIMARY KEY (ID1, ID2)
);
DROP TABLE IF EXISTS #t;
SELECT TOP (4000) 0 ID INTO #t
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);
INSERT INTO dbo.two_col_key_test WITH (TABLOCK)
SELECT N'FILLER TEXT' + CASE WHEN ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) > 8000000 THEN N' 2' ELSE N'' END
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, NULL
FROM #t t1
CROSS JOIN #t t2;
콜 스택보고보다 더 많은 답변을 원합니다. 예를 들어sqlmin!TCValSSInRowExprFilter<231,0,0>::GetDataX
빠른 쿼리와 비교할 때 느린 쿼리에서 CPU주기가 훨씬 더 많이 걸린다 .
거기서 멈추지 않고 그게 무엇인지, 왜 두 쿼리 사이에 큰 차이가 있는지 이해하고 싶습니다.
이 두 쿼리에 대해 CPU 시간에 큰 차이가있는 이유는 무엇입니까?