Сбивающие с толку рекомендации по производительности от SQL Server Management Studio

#sql #sql-server #tsql #database-indexes #sql-server-performance

#sql #sql-сервер #tsql #база данных-индексы #sql-server-производительность

Вопрос:

Я работаю над улучшением производительности нашего SQL. И SQL Server Management Studio дала совет, который меня удивил. Ради примера я собираюсь упростить структуру таблицы и рекомендации, которые дал SSMS.

Структура таблицы Person:

  • ID
  • first_name
  • last_name
  • date_of_birth
  • Адрес электронной почты

У меня был конкретный запрос, для которого я показал план выполнения. Затем я увидел совет, который дал SSMS, и это меня немного удивило. Рекомендуется добавить два индекса со следующей подписью, что должно повысить производительность на 41% и 53% соответственно:

 CREATE NONCLUSTERED INDEX [person_1]
  ON [Person]([first_name],[last_name])
  INCLUDE ([id],[date_of_birth],[email])

CREATE NONCLUSTERED INDEX [person_2]
  ON [Person]([first_name],[last_name])
  INCLUDE ([id],[email])
  

Эти два индекса находятся в одних и тех же столбцах. Отличаются только столбцы INCLUDE. Насколько я понял из чтения об индексах, первый индекс также включает данные для второго индекса. Итак, почему SSMS рекомендует второй индекс, а также первый, который уже включает необходимые данные?

Комментарии:

1. Я не могу объяснить, почему SSMS рекомендует оба индекса. Как вы заметили, первый индекс является надмножеством второго, поэтому второй не нужен. Я предполагаю, что у вас очень сложный запрос, и разные части запроса могут использовать тот или иной индекс. В качестве альтернативы, может существовать тонкое различие между индексами, которые делают их разными, например, столбец в порядке убывания.

2. Я согласен с вами. Второй не имеет значения, если у вас уже есть первый. Возможно … это могло бы быть немного быстрее, если ваш запрос не использует столбец date_of_birth ; но разница, вероятно, незначительна.

3. Спасибо вам обоим за ваши мнения. Приведенный мной пример действительно является упрощением очень большого и сложного запроса. Я вроде как доверял SSMS, но рецензент сказал, что он не понял этот совет. Хорошая вещь, чтобы снова не доверять ему слепо.

Ответ №1:

Никогда не используйте предложение SSMS как предоставленное. Предложение основано на конкретном запросе.

Лучше изучите системные представления, такие как sys.dm_db_missing_index_details. Смотрите больше на sys.dm_db_missing_index_details

или ознакомьтесь с запросами DMV Гленна Берри в запросах диагностической информации SQL Server за апрель 2019 года

… или еще лучше взять Brent Ozar sp_blitzindex BrentOzarULTD/SQL-Server-First-Responder-Kit

… или возьмите этот запрос

 SELECT DB_NAME(database_id) AS database_name, 
       OBJECT_NAME(object_id, database_id) AS table_name, 
       mid.equality_columns, 
       mid.inequality_columns, 
       mid.included_columns, 
       (migs.user_seeks   migs.user_scans) * migs.avg_user_impact AS Impact, 
       migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks   migs.user_scans) AS Score, 
       migs.user_seeks, 
       migs.user_scans
FROM sys.dm_db_missing_index_details mid
     INNER JOIN sys.dm_db_missing_index_groups mig ON mid.index_handle = mig.index_handle
     INNER JOIN sys.dm_db_missing_index_group_stats migs ON mig.index_group_handle = migs.group_handle
ORDER BY migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks   migs.user_scans) DESC;