Tôi đang hỏi câu hỏi này để hiểu rõ hơn về hành vi của trình tối ưu hóa và để hiểu các giới hạn xung quanh các cuộn chỉ số. Giả sử tôi đặt các số nguyên từ 1 đến 10000 thành một đống:
CREATE TABLE X_10000 (ID INT NOT NULL);
truncate table X_10000;
INSERT INTO X_10000 WITH (TABLOCK)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Và buộc một vòng lặp lồng nhau tham gia với MAXDOP 1
:
SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Đây là một hành động khá không thân thiện đối với SQL Server. Các vòng lặp lồng nhau thường không phải là một lựa chọn tốt khi cả hai bảng không có bất kỳ chỉ mục liên quan nào. Đây là kế hoạch:
Truy vấn mất 13 giây trên máy của tôi với 100000000 hàng được tìm nạp từ bộ đệm bảng. Tuy nhiên, tôi không thấy lý do tại sao truy vấn phải chậm. Trình tối ưu hóa truy vấn có khả năng tạo các chỉ mục một cách nhanh chóng thông qua các cuộn chỉ mục . Truy vấn này có vẻ như là một ứng cử viên hoàn hảo cho một bộ đệm chỉ mục.
Truy vấn sau đây trả về kết quả giống như truy vấn đầu tiên, có bộ đệm chỉ mục và kết thúc sau chưa đầy một giây:
SELECT *
FROM X_10000 a
CROSS APPLY (SELECT TOP (9223372036854775807) b.ID FROM X_10000 b WHERE a.ID = b.ID) ca
OPTION (LOOP JOIN, MAXDOP 1);
Truy vấn này cũng có một bộ đệm chỉ mục và kết thúc sau chưa đầy một giây:
SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Tại sao truy vấn ban đầu không có bộ đệm chỉ mục? Có bất kỳ tập hợp các gợi ý tài liệu hoặc không có giấy tờ hoặc cờ theo dõi sẽ cung cấp cho nó một bộ chỉ mục không? Tôi đã tìm thấy câu hỏi liên quan này , nhưng nó không trả lời đầy đủ câu hỏi của tôi và tôi không thể làm cho cờ theo dõi bí ẩn hoạt động cho truy vấn này.