#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;