Indexes can be incredibly beneficial to your database performance; however, they do come with a cost—indexes both consume storage space and affect insert performance. Therefore, it is important as part of your index maintenance procedures that you periodically check to see if your indexes are being used. Many times, indexes are created in the belief they are needed but in fact they are never used. You can reduce that IO overhead on inserts when you remove unnecessary indexes.
How Do You Find Them?
Glenn Berry (B|T) has a fantastic script as part of his diagnostic scripts (link) that helps identify index utilization. In his diagnostic scripts it is listed as Script # 53.
- -- Possible Bad NC Indexes (writes > reads) (Query 53) (Bad NC Indexes)
- SELECT d.name,OBJECT_NAME(s.[object_id]) AS [Table Name],
- i.name AS [Index Name], i.index_id,i.is_disabled, i.is_hypothetical,
- i.has_filter, i.fill_factor,user_updates AS [Total Writes],
- user_seeks + user_scans + user_lookups AS [Total Reads],
- user_updates - (user_seeks + user_scans + user_lookups) AS [Difference],
- 'USE ' + QUOTENAME(d.name) + '; ALTER INDEX ' + QUOTENAME(i.name) +' ON ' +OBJECT_NAME(s.[object_id]) +' DISABLE '; as statement
- FROM sys.dm_db_index_usage_stats AS s WITH (NOLOCK)
- INNER JOIN sys.indexes AS i WITH (NOLOCK)
- ON s.[object_id] = i.[object_id]
- AND i.index_id = s.index_id
- join sys.databases d on d.database_id=s.database_id
- WHERE OBJECTPROPERTY(s.[object_id],'IsUserTable') = 1
- AND s.database_id = DB_ID()
- AND user_updates > (user_seeks + user_scans + user_lookups)
- AND i.index_id > 1
- and i.name not like 'PK%'
- and i.name not like 'f%'
- ORDER BY [Difference] DESC,
- [Total Writes] DESC,
- [Total Reads] AS C OPTION (RECOMPILE);


Pankajkumar PatelPosted Aug 30, 2019, 12:50 AM
Nice article