Индексы SQL Server, по сути, являются копиями данных, которые уже существуют в таблице, упорядочены и отфильтрованы различными способами для повышения производительности выполненных запросов.Операторы поиска, сканирования и поиска используются для доступа к индексам SQL Server.
Операторы поиска - оператор Seek использует возможность SQL Server для поиска в индексах для получения строк из кластеризованных или некластеризованных индексов.и поиск может быть как физическим, так и логическим оператором.Индекс поиска имеет дело только с квалифицированными строками и со страницами, которые содержат эти квалифицированные строки, и поэтому стоимость поиска дешевле.Проще говоря, стремится извлечь только выбранные строки из таблицы.
Операторы сканирования - оператор сканирования сканирует кластеризованный индекс и предназначен для работы с каждой строкой в отсканированной таблице.независимо от того, является ли строка квалифицированной или нет.Оператор сканирования может быть эффективен для небольших таблиц или в ситуации, когда большинство строк квалифицированы.Проще говоря, при сканировании извлекаются все строки из таблицы.
Операторы поиска - оператор поиска, используется для извлечения неключевых данных из набора результатов, извлеченного из некластеризованного индекса,После извлечения строк из некластеризованного индекса для получения информации о столбцах из этих строк используются поиски.
Хотя правильное использование индексов SQL Server может повысить производительность выполненных запросов и, следовательно, SQL Server в целом, настройканеправильная настройка или неправильная установка их в случае необходимости может значительно снизить производительность выполняемых запросов.Более того, наличие ненужных индексов, которые не используются запросами, также может быть проблематичным.
Индексы SQL Server являются отличным инструментом для повышения производительности запросов SELECT, но в то же время индексы SQL Server оказывают негативное влияние.на обновления данных.Операции INSERT, UPDATE и DELETE вызывают обновление индекса и, следовательно, дублируют данные, которые уже существуют в таблице.В результате это увеличивает продолжительность транзакций и выполнения запроса и часто может привести к блокировке, блокировке, взаимной блокировке и довольно частым тайм-аутам выполнения.Для больших баз данных или таблиц на пространство хранения также влияют избыточные индексы.Важной целью любого администратора БД SQL Server является поддержание индексов, включая создание необходимых индексов, но в то же время удаление тех, которые не используются.
Поиск неиспользуемых индексов
SQL Server предоставляет значительный объем индексной информации через динамические административные представления (DMV).DMV dm_db_index_usage_stats отображает важную информацию об использовании индекса и может быть полезным инструментом для определения неиспользуемых индексов SQL Server.Когда индекс используется впервые, в dm_db_index_usage_stats
DMV создается новая строка и впоследствии обновляется каждый раз, когда используется индекс.Однако, как и для каждого DMV, данные, присутствующие в dm_db_index_usage_stats, содержат только данные с момента последнего перезапуска службы SQL Server (перезапуск службы SQL Server сбрасывает данные в DMV).Поэтому крайне важно, чтобы с момента последнего перезапуска SQL Server было достаточно времени, позволяющего правильно определить, какие индексы являются хорошими кандидатами для удаления.
Простой запрос, который можно использовать для получения списка неиспользуемых индексов.в SQL Server (обновленные индексы не используются ни в каких операциях поиска, сканирования или поиска) выглядит следующим образом:
SELECT
objects.name AS Table_name,
indexes.name AS Index_name,
dm_db_index_usage_stats.user_seeks,
dm_db_index_usage_stats.user_scans,
dm_db_index_usage_stats.user_updates
FROM
sys.dm_db_index_usage_stats
INNER JOIN sys.objects ON dm_db_index_usage_stats.OBJECT_ID = objects.OBJECT_ID
INNER JOIN sys.indexes ON indexes.index_id = dm_db_index_usage_stats.index_id AND dm_db_index_usage_stats.OBJECT_ID = indexes.OBJECT_ID
WHERE
AND
dm_db_index_usage_stats.user_lookups = 0
AND
dm_db_index_usage_stats.user_seeks = 0
AND
dm_db_index_usage_stats.user_scans = 0
ORDER BY
dm_db_index_usage_stats.user_updates DESC
Приведенный выше запрос возвращает все неиспользуемые индексы всех типов.Этот запрос часто можно найти в Интернете, но он не является идеальным / полным вариантом.Использование такого запроса для поиска и очистки неиспользуемых индексов может привести к неожиданному поведению, поскольку этот запрос не учитывает ограничения первичного ключа и уникального ключа при сборе данных неиспользуемого индекса.И индексы ограничений первичного, и уникального ключа могут быть «неиспользованными», но удаление этих индексов может быть проблематичным.Чтобы предотвратить этот сценарий, приведенный выше запрос необходимо уточнить, добавив две строки кода после WHERE, чтобы исключить первичные и уникальные ключи из списка неиспользованных и потенциально удаленных.
SELECT
objects.name AS Table_name,
indexes.name AS Index_name,
dm_db_index_usage_stats.user_seeks,
dm_db_index_usage_stats.user_scans,
dm_db_index_usage_stats.user_updates
FROM
sys.dm_db_index_usage_stats
INNER JOIN sys.objects ON dm_db_index_usage_stats.OBJECT_ID = objects.OBJECT_ID
INNER JOIN sys.indexes ON indexes.index_id = dm_db_index_usage_stats.index_id AND dm_db_index_usage_stats.OBJECT_ID = indexes.OBJECT_ID
WHERE
indexes.is_primary_key = 0 -- This condition excludes primary key constarint
AND
indexes. is_unique = 0 -- This condition excludes unique key constarint
AND
dm_db_index_usage_stats. user_lookups = 0
AND
dm_db_index_usage_stats.user_seeks = 0
AND
dm_db_index_usage_stats.user_scans = 0
ORDER BY
dm_db_index_usage_stats.user_updates DESC
В приведенном выше запросе перечислены всенеиспользуемые запросы, которые не являются первичными и уникальными ключами, но в нем также перечислены все неиспользуемые индексы, с которыми SQL Server не работал.Столбец user_updates в DMV dm_db_index_usage_stats считает, где индекс был обновлен, так как приложение внесло некоторые изменения в данные, поэтому индекс был обновлен.Для этого необходимо добавить условия dm_db_index_usage_stats.user_updates <> 0
в предыдущий сценарий.
SELECT
objects.name AS Table_name,
indexes.name AS Index_name,
dm_db_index_usage_stats.user_seeks,
dm_db_index_usage_stats.user_scans,
dm_db_index_usage_stats.user_updates
FROM
sys.dm_db_index_usage_stats
INNER JOIN sys.objects ON dm_db_index_usage_stats.OBJECT_ID = objects.OBJECT_ID
INNER JOIN sys.indexes ON indexes.index_id = dm_db_index_usage_stats.index_id AND dm_db_index_usage_stats.OBJECT_ID = indexes.OBJECT_ID
WHERE
indexes.is_primary_key = 0 --This line excludes primary key constarint
AND
indexes. is_unique = 0 --This line excludes unique key constarint
AND
dm_db_index_usage_stats.user_updates <> 0 -- This line excludes indexes SQL Server hasn’t done any work with
AND
dm_db_index_usage_stats. user_lookups = 0
AND
dm_db_index_usage_stats.user_seeks = 0
AND
dm_db_index_usage_stats.user_scans = 0
ORDER BY
dm_db_index_usage_stats.user_updates DESC
Так что теперь, когда неиспользуемые индексы SQL Server определены и перечислены, можно определить, какие индексы можно безопасно удалить, но сноваэто должно быть сделано очень осторожно.