Это интересный вопрос. Я занимаюсь этим вопросом в течение прошлой недели. Существует системная таблица с именем dm_db_index_usage_stats, которая содержит статистику использования индексов.
Индексы, которые никогда не появляются в таблице статистики использования
Однако многие показатели никогда не появляются в этой таблице вообще. В запросе Дэвида Андреса были перечислены все индексы для этого случая. Я немного обновил его, чтобы игнорировать первичные ключи, которые, вероятно, не следует удалять, даже если они никогда не используются. Я также присоединился к таблице dm_db_index_physical_stats, чтобы получить другую информацию, включая количество страниц, общий размер индекса и процент фрагментации. Интересно отметить, что индексы, возвращаемые этим запросом, как представляется, не отображаются в SQL-отчете для статистики использования индексов.
DECLARE @dbid INT
SELECT @dbid = DB_ID(DB_NAME())
SELECT Databases.Name AS [Database],
Objects.NAME AS [Table],
Indexes.NAME AS [Index],
Indexes.INDEX_ID,
PhysicalStats.page_count as [Page Count],
CONVERT(decimal(18,2), PhysicalStats.page_count * 8/1024.0) AS [Total Index Size (MB)],
CONVERT(decimal(18,2), PhysicalStats.avg_fragmentation_in_percent) AS [Fragmentation (%)]
FROM SYS.INDEXES Indexes
INNER JOIN SYS.OBJECTS Objects ON Indexes.OBJECT_ID = Objects.OBJECT_ID
LEFT JOIN sys.dm_db_index_physical_stats(@dbid, null, null, null, null) PhysicalStats
on PhysicalStats.object_id = Indexes.object_id and PhysicalStats.index_id = indexes.index_id
INNER JOIN sys.databases Databases
ON Databases.database_id = PhysicalStats.database_id
WHERE OBJECTPROPERTY(Objects.OBJECT_ID,'IsUserTable') = 1
AND Indexes.type = 2 -- Nonclustered indexes
AND Indexes.INDEX_ID NOT IN (
SELECT UsageStats.INDEX_ID
FROM SYS.DM_DB_INDEX_USAGE_STATS UsageStats
WHERE UsageStats.OBJECT_ID = Indexes.OBJECT_ID
AND Indexes.INDEX_ID = UsageStats.INDEX_ID
AND DATABASE_ID = @dbid)
ORDER BY PhysicalStats.page_count DESC,
Objects.NAME,
Indexes.INDEX_ID,
Indexes.NAME ASC
индексы, которые появляются в таблице статистики использования, но никогда не используются
Есть и другие показатели, которые появляются в таблице dm_db_index_usage_stats, но которые никогда не были использованы для пользователей ищет, сканы , или поисковые запросы. В этом запросе будут указаны индексы, попадающие в эту категорию. Кстати, в отличие от индексов, возвращаемых из другого запроса, индексы, возвращаемые в этом запросе, могут быть проверены в SQL-отчете по статистике использования индексов.
Я добавил минимальное количество страниц, что позволяет мне сначала сосредоточиться и удалить неиспользуемые индексы, которые занимают много места.
DECLARE @MinimumPageCount int
SET @MinimumPageCount = 500
SELECT Databases.name AS [Database],
Indexes.name AS [Index],
Objects.Name AS [Table],
PhysicalStats.page_count as [Page Count],
CONVERT(decimal(18,2), PhysicalStats.page_count * 8/1024.0) AS [Total Index Size (MB)],
CONVERT(decimal(18,2), PhysicalStats.avg_fragmentation_in_percent) AS [Fragmentation (%)],
ParititionStats.row_count AS [Row Count],
CONVERT(decimal(18,2), (PhysicalStats.page_count * 8.0 * 1024)/ParititionStats.row_count) AS [Index Size/Row (Bytes)]
FROM sys.dm_db_index_usage_stats UsageStats
INNER JOIN sys.indexes Indexes
ON Indexes.index_id = UsageStats.index_id
AND Indexes.object_id = UsageStats.object_id
INNER JOIN sys.objects Objects
ON Objects.object_id = UsageStats.object_id
INNER JOIN SYS.databases Databases
ON Databases.database_id = UsageStats.database_id
INNER JOIN sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS PhysicalStats
ON PhysicalStats.index_id = UsageStats.Index_id
and PhysicalStats.object_id = UsageStats.object_id
INNER JOIN SYS.dm_db_partition_stats ParititionStats
ON ParititionStats.index_id = UsageStats.index_id
and ParititionStats.object_id = UsageStats.object_id
WHERE UsageStats.user_scans = 0
AND UsageStats.user_seeks = 0
AND UsageStats.user_lookups = 0
AND PhysicalStats.page_count > @MinimumPageCount -- ignore indexes with less than 500 pages of memory
AND Indexes.type_desc != 'CLUSTERED' -- Exclude primary keys, which should not be removed
ORDER BY [Page Count] DESC
Надеюсь, это поможет.
Заключительные мысли
Конечно, когда индексы определены как кандидатов для удаления, серьезное внимание следует по-прежнему можно использовать, чтобы убедиться, что это хорошее решение, чтобы сделать это.
Для получения дополнительной информации см Identifying Unused Indexes in a SQL Server Database