Я задаю це запитання, щоб краще зрозуміти поведінку оптимізатора і зрозуміти межі навколо котушок індексу. Припустимо, я поклав цілі числа від 1 до 10000 у купу:
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;
І змусити вкладений цикл з'єднатись із MAXDOP 1
:
SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Це досить недружні дії, спрямовані на SQL Server. Вкладений цикл з'єднання часто не є хорошим вибором, коли в обох таблицях немає відповідних індексів. Ось план:
На моїй машині запит займає 13 секунд, із 100000000 рядків, зібраних із котушки таблиці. Однак я не бачу, чому запит має бути повільним. Оптимізатор запитів має можливість створювати індекси під час руху через котушки індексів . Цей запит, схоже, був би ідеальним кандидатом на індексну котушку.
Наступний запит повертає ті ж результати, що і перший, має індексну котушку і закінчується менше ніж за секунду:
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);
Цей запит також має індексну котушку і закінчується менше ніж за секунду:
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);
Чому оригінальний запит не містить котушки індексу? Чи є якийсь набір документально підтверджених або недокументованих натяків чи слідів, які дадуть йому індексну котушку? Я знайшов це пов’язане питання , але воно не відповідає повністю на моє запитання, і я не можу заставити загадковий слід прапора для роботи над цим запитом.