Điều này hơi rộng nhưng tôi nghĩ tôi hiểu Câu hỏi thật và sẽ trả lời tương ứng. Chỉ cần nói về bảng vs chỉ số mặc dù. Tôi không nghĩ nó hoàn toàn chính xác khi xem đó là sự lựa chọn giữa các cuộn bảng và chỉ mục. Như bạn đã biết, có thể trong một cây con duy nhất để có được một bộ đệm chỉ mục, bộ đệm bảng hoặc cả bộ đệm chỉ mục và bộ đệm bảng. Tôi tin rằng nói chung là chính xác khi nói rằng bạn nhận được một bộ chỉ mục theo các điều kiện sau:
- Trình tối ưu hóa truy vấn có lý do để chuyển đổi một tham gia thành một ứng dụng
- Trình tối ưu hóa truy vấn thực sự thực hiện chuyển đổi để áp dụng
- Trình tối ưu hóa truy vấn sử dụng quy tắc để thêm một bộ đệm chỉ mục (tối thiểu bộ đệm chỉ mục phải an toàn để sử dụng)
- Kế hoạch với bộ chỉ mục được chọn
Bạn có thể thấy hầu hết những thứ này với các bản demo đơn giản. Bắt đầu bằng cách tạo một cặp đống:
DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_901;
CREATE TABLE dbo.X_10000_VARCHAR_901 (ID VARCHAR(901) NOT NULL);
INSERT INTO dbo.X_10000_VARCHAR_901 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_800;
CREATE TABLE dbo.X_10000_VARCHAR_800 (ID VARCHAR(800) NOT NULL);
INSERT INTO dbo.X_10000_VARCHAR_800 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Đối với truy vấn đầu tiên, không có gì để tìm kiếm:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
CROSS JOIN dbo.X_10000_VARCHAR_901 b
OPTION (MAXDOP 1);
Vì vậy, không có lý do gì để trình tối ưu hóa chuyển đổi tham gia thành một ứng dụng. Bạn kết thúc với một bộ đệm bảng vì lý do chi phí. Vì vậy, truy vấn này thất bại trong bài kiểm tra đầu tiên.
Đối với truy vấn tiếp theo, thật công bằng khi hy vọng rằng trình tối ưu hóa có lý do để xem xét áp dụng:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Nhưng nó không có nghĩa là:
Truy vấn này thất bại trong bài kiểm tra thứ hai. Một lời giải thích đầy đủ là ở đây . Trích dẫn phần có liên quan nhất:
Trình tối ưu hóa không xem xét việc xây dựng một chỉ mục một cách nhanh chóng để cho phép áp dụng; thay vì chuỗi các sự kiện thường là ngược lại: biến đổi để áp dụng vì tồn tại một chỉ số tốt.
Tôi có thể viết lại truy vấn để khuyến khích trình tối ưu hóa xem xét áp dụng:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (MAXDOP 1);
Nhưng vẫn không có chỉ số spool:
Truy vấn này thất bại trong bài kiểm tra thứ ba. Trong SQL Server 2014, có giới hạn độ dài khóa chỉ mục là 900 byte. Điều này đã được mở rộng trong SQL Server 2016 nhưng chỉ dành cho các chỉ mục không bao gồm. Chỉ mục cho một bộ đệm là một chỉ mục được nhóm lại, do đó giới hạn vẫn ở mức 900 byte . Trong mọi trường hợp, quy tắc bộ đệm chỉ mục không thể được áp dụng vì nó có thể dẫn đến lỗi trong khi thực hiện truy vấn.
Việc giảm độ dài kiểu dữ liệu xuống 800 cuối cùng cũng cung cấp một gói với bộ đệm chỉ mục:
Kế hoạch bộ đệm chỉ mục, không đáng ngạc nhiên, có chi phí rẻ hơn đáng kể so với kế hoạch không có bộ đệm: 89.7603 đơn vị so với 598.832 đơn vị. Bạn có thể thấy sự khác biệt với QUERYRULEOFF BuildSpool
gợi ý truy vấn không có giấy tờ :
Đây không phải là một câu trả lời hoàn chỉnh, nhưng hy vọng đó là một số thứ bạn đang tìm kiếm.