Чому SQL Server не містить відсутніх запитів на індекс у DMV або Планах запитів?


14

У мене є база даних SQL Server, де запити доволі повільні, і є багато блокування та блокування.

Коли я дивлюся на відсутні індекси DMV та плани запитів, немає пропозицій.

Чому так?

Відповіді:


17

Є багато причин, через які у вас може бути відсутніх запитів на індекс!

Ми розглянемо кілька причин більш докладно, а також поговоримо про деякі загальні обмеження функції.

Загальні обмеження

По-перше, з: Обмеження відсутніх показників :

  • Він не визначає замовлення для використання стовпців в індексі.

Як зазначено в цьому запитанні: Як SQL Server визначає порядок стовпців ключів у відсутніх запитах на індекс? , порядок стовпців у визначенні індексу продиктовано предикатом рівності проти нерівності, а потім порядковим розташуванням стовпців у таблиці.

Немає здогадів про вибірковість, і може бути кращий порядок. Ваша робота розібратися в цьому.

Спеціальні покажчики

Відсутні запити на індекс також не охоплюють "спеціальні" індекси, як-от:

  • Скупчений
  • Відфільтровано
  • Розділені
  • Стиснута
  • XML-ред
  • Просторовий ред
  • Columnstore-d
  • Індексований перегляд-ред

Які стовпці вважаються?

Відсутній стовпець ключових індексів створюється з стовпців, які використовуються для фільтрації результатів, як-от у:

  • ПРИЄДНАЄТЬСЯ
  • ДЕ ЗАКЛАД

Стовпці, що відсутні в індексі, генеруються із стовпців, необхідних для запиту, таких як:

  • ВИБІРИ
  • ГРУПА ПО
  • СОРТУВАТИ ПО

Хоча досить часто стовпці, які ви замовляєте або групуєте, можуть бути корисними як ключові стовпці. Це повертається до одного з обмежень:

  • Він не призначений для тонкої настройки конфігурації індексування.

Наприклад, цей запит не буде реєструвати відсутній запит на індекс, навіть якщо додавання індексу на LastAccessDate запобіжить необхідності сортування (та розсипання на диск).

SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;

Горіхи

Це також не запитує групування за адресою Location.

SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location

Горіхи

Це не дуже корисно!

Ну так, але це краще, ніж нічого. Подумайте про відсутність запитів на індекс, як плаче дитина. Ви знаєте, що є проблема, але ви, дорослий, вирішити, що це за проблема.

Ви все ще не сказали мені, чому я їх не маю, хоча ...

Розслабся, букко. Ми туди потрапляємо.

Сліди прапорів

Якщо ввімкнути TF 2330 , запити про відсутні індекси не будуть реєструватися. Щоб дізнатися, чи увімкнено це, запустіть це:

DBCC TRACESTATUS;

Поновлення індексу

Перебудова індексів очистить пропущені запити на індекс. Тож перш ніж вирушати на пристрій Hi-Ho-Silver-Away, будуючи кожен індекс, вдруге прокрадеться йота фрагментації, подумайте над інформацією, яку ви очищаєте щоразу, коли це робите.

Ви також можете задуматися над тим, чому дефрагментація ваших індексів все-таки не допомагає . Якщо ви не використовуєте Columnstore .

Додавання, видалення або відключення індексів

Додавання, видалення або відключення індексу видалить усі пропущені запити щодо індексу для цієї таблиці. Якщо ви працюєте над декількома змінами індексу в одній таблиці, переконайтеся, що ви їх все сценарії, перш ніж робити будь-які.

Тривіальні плани

Якщо план досить простий, а вибір доступу до індексу досить очевидний, а вартість досить низька, ви отримаєте тривіальний план.

Це фактично означає, що оптимізатор не міг приймати рішення на основі витрат.

Via Paul White :

Деталі того, які типи запитів можуть отримати користь від Trivial Plan, часто змінюються, але такі речі, як приєднання, підзапити та предикати нерівності, як правило, перешкоджають цій оптимізації.

Якщо план тривіальний, додаткові фази оптимізації не досліджуються, а відсутні індекси не запитуються .

Дивіться різницю між цими запитами та їхніми планами :

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);

Горіхи

Перший план тривіальний, і запит не відображається. Можуть бути випадки, коли помилки запобігають появі відсутніх індексів у планах запитів; вони, як правило, більш надійно заносяться до відсутніх індексів DMV.

SARGability

Визначає, де оптимізатор не зміг би ефективно використовувати індекс навіть із індексом, може не допустити їх реєстрації.

Речі, які, як правило, не є SARGable:

  • Стовпці, загорнуті у функції
  • Стовпець + SomeValue = SomePredicate
  • Стовпець + AnotherColumn = SomePredicate
  • Стовпець = @ Варіабельний АБО @ Варіабельний NULL

Приклади:

SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;


SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000


SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000


DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo 
      OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;

Жоден із цих запитів не реєструє відсутні запити на індекс. Для отримання додаткової інформації про них перегляньте наступні посилання:

У вас вже є нормальний індекс

Візьміть цей індекс:

CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);

Це запит виглядає нормально:

SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND   p.CreationDate < '20181231'
AND   p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;

План простий пошук ...

Горіхи

Але оскільки провідний стовпчик ключових значень для менш вибіркового предиката, ми в кінцевому підсумку робимо більше роботи, ніж ми повинні:

Таблиця "Повідомлення". Кількість сканувань 13, логічне зчитування 136890

Якщо ми змінимо порядок стовпців ключових індексів, ми зробимо набагато менше роботи:

CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);

Горіхи

І значно менше читає:

Таблиця "Повідомлення". Кількість сканувань 1, логічне зчитування 5

SQL Server створює для вас індекси

У певних випадках SQL Server вирішить створити індекс на ходу за допомогою індексної котушки. Якщо котушка індексу присутня, відсутній запит на індекс не буде. Безумовно, самостійно додавати індекс може бути хорошою ідеєю, але не розраховуйте, що SQL Server допоможе вам розібратися.

Горіхи

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.