Saya mengajukan pertanyaan ini untuk lebih memahami perilaku pengoptimal dan untuk memahami batas-batas di sekitar gulungan indeks. Misalkan saya menaruh bilangan bulat dari 1 hingga 10.000 ke dalam tumpukan:
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;
Dan paksa loop bersarang bergabung dengan MAXDOP 1
:
SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Ini adalah tindakan yang agak tidak ramah untuk dilakukan terhadap SQL Server. Nested loop bergabung sering bukan pilihan yang baik ketika kedua tabel tidak memiliki indeks yang relevan. Inilah rencananya:
Permintaan membutuhkan waktu 13 detik pada mesin saya dengan 10.0000000 baris diambil dari tabel spool. Namun, saya tidak melihat mengapa permintaan harus lambat. Pengoptimal kueri memiliki kemampuan untuk membuat indeks dengan cepat melalui gulungan indeks . Kueri ini sepertinya akan menjadi kandidat yang sempurna untuk spool indeks.
Kueri berikut mengembalikan hasil yang sama dengan yang pertama, memiliki spool indeks, dan selesai dalam waktu kurang dari satu detik:
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);
Kueri ini juga memiliki spool indeks dan selesai dalam waktu kurang dari satu detik:
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);
Mengapa kueri asli tidak memiliki spool indeks? Apakah ada set petunjuk atau jejak bendera yang didokumentasikan atau tidak berdokumen yang akan memberikan indeks spool? Saya memang menemukan pertanyaan terkait ini , tetapi itu tidak sepenuhnya menjawab pertanyaan saya dan saya tidak bisa mendapatkan tanda jejak misterius untuk bekerja untuk permintaan ini.
sumber