DBAtlas · Атлас эксплуатации баз данных

Поиск неиспользуемых / только записываемых индексов

SQL ServerОбслуживание

Команда

USE [Musteri];
SELECT OBJECT_SCHEMA_NAME(i.object_id) AS schema_name,
       OBJECT_NAME(i.object_id)        AS table_name,
       i.name                          AS index_name,
       ISNULL(us.user_seeks, 0) + ISNULL(us.user_scans, 0) + ISNULL(us.user_lookups, 0) AS reads,
       ISNULL(us.user_updates, 0)      AS writes,
       ps.used_mb,
       us.last_user_seek, us.last_user_scan,
       N'DROP INDEX ' + QUOTENAME(i.name) + N' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id))
         + N'.' + QUOTENAME(OBJECT_NAME(i.object_id)) + N';' AS drop_stmt_draft
FROM   sys.indexes i
  LEFT JOIN sys.dm_db_index_usage_stats us
         ON us.database_id = DB_ID() AND us.object_id = i.object_id AND us.index_id = i.index_id
  CROSS APPLY (SELECT CAST(SUM(p.used_page_count) * 8 / 1024.0 AS DECIMAL(18,1)) AS used_mb
               FROM sys.dm_db_partition_stats p
               WHERE p.object_id = i.object_id AND p.index_id = i.index_id) ps
WHERE  OBJECTPROPERTY(i.object_id, 'IsUserTable') = 1
  AND  i.type_desc = N'NONCLUSTERED'
  AND  i.is_primary_key = 0 AND i.is_unique_constraint = 0 AND i.is_unique = 0
  AND  ISNULL(us.user_seeks, 0) + ISNULL(us.user_scans, 0) + ISNULL(us.user_lookups, 0) = 0
ORDER BY writes DESC, ps.used_mb DESC;

-- Usage counters since:
SELECT sqlserver_start_time FROM sys.dm_os_sys_info;

Что делает

Выводит некластеризованные индексы, которые не читались (seek/scan/lookup = 0) с момента перезапуска, но по-прежнему несут стоимость записи, с их размером и генерирует черновик DROP INDEX.

Когда использовать

При медленных INSERT/UPDATE на таблицах с интенсивной записью, для сокращения места и времени обслуживания (rebuild, CHECKDB) или перед консолидацией индексов.

Внимание

Счётчики сбрасываются при перезапуске, переводе базы в офлайн/отсоединении и (в некоторых старых сборках 2012/2014) при перестроении индекса; индексы, используемые только отчётами конца месяца/года, в коротком окне выглядят "неиспользуемыми". Перед удалением наблюдайте хотя бы один полный бизнес-цикл, а в AG проверяйте использование на читаемых вторичных репликах отдельно (счётчики — на каждой реплике свои). Уникальные индексы обеспечивают ограничения, даже если не читаются; они исключены. Запрос только на чтение; безопасно.

Открыть в DBAtlas →

Связанные материалы