Tôi đã có thể tái tạo một vấn đề hiệu năng truy vấn mà tôi sẽ mô tả là bất ngờ. Tôi đang tìm kiếm một câu trả lời tập trung vào nội bộ.
Trên máy của tôi, truy vấn sau đây thực hiện quét chỉ mục theo cụm và mất khoảng 6,8 giây thời gian 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);
Truy vấn sau đây thực hiện tìm kiếm chỉ mục theo cụm (chỉ khác là xóa FORCESCAN
gợi ý) nhưng mất khoảng 18,2 giây thời gian 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);
Các kế hoạch truy vấn là khá giống nhau. Đối với cả hai truy vấn, có 120000001 hàng được đọc từ chỉ mục được nhóm:
Tôi đang trên SQL Server 2017 CU 10. Đây là mã để tạo và điền vào two_col_key_test
bảng:
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;
Tôi hy vọng cho một câu trả lời không chỉ là báo cáo ngăn xếp cuộc gọi. Ví dụ, tôi có thể thấy rằng sqlmin!TCValSSInRowExprFilter<231,0,0>::GetDataX
cần nhiều chu kỳ CPU hơn trong truy vấn chậm so với truy vấn nhanh:
Thay vì dừng lại ở đó, tôi muốn hiểu đó là gì và tại sao có sự khác biệt lớn như vậy giữa hai truy vấn.
Tại sao có sự khác biệt lớn về thời gian CPU cho hai truy vấn này?