Find Indexes Not In Use in SQL Server Print E-mail
Tuesday, 22 November 2011 19:12

 

from http://sqlserverpedia.com/wiki/Find_Indexes_Not_In_Use

See Also: Main_Page - Transact SQL Code Library - Index Performance Tuning

 

This query can help identify indexes that have not been used since the last restart.  You can also switch the sort order to see your heavily used indexes.

 

The "reads_per_write" field helps to find indexes that aren't helping to improve performance.  For every 1 write to the index, you want to see as many reads as possible.  Indexes with a reads_per_write score of 1 mean that for every 1 write, the index is also used 1 time to help with performance.  Ideally, you want to see scores much higher than that.  Consider dropping indexes with a reads_per_write score under zero, and strongly consider dropping ones with scores under .1.

 

This isn't a hard-and-fast rule: for example, you may have an index that's only used once per month for a single report, but that report is run by the CEO and he wants it instantaneously.  Before dropping indexes, know what they're used for, or make sure alternate indexes exist.  Alternate indexes would be indexes that are wider than the index you're dropping, and include enough fields to serve the query's needs.

 

SELECT

o.name

, indexname=i.name

, i.index_id

, reads=user_seeks + user_scans + user_lookups

, writes =  user_updates

, rows = (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id)

, CASE

WHEN s.user_updates < 1 THEN 100

ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates

END AS reads_per_write

, 'DROP INDEX ' + QUOTENAME(i.name)

+ ' ON ' + QUOTENAME(c.name) + '.' + QUOTENAME(OBJECT_NAME(s.object_id)) as 'drop statement'

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON i.index_id = s.index_id AND s.object_id = i.object_id

INNER JOIN sys.objects o on s.object_id = o.object_id

INNER JOIN sys.schemas c on o.schema_id = c.schema_id

WHERE OBJECTPROPERTY(s.object_id,'IsUserTable') = 1

AND s.database_id = DB_ID()

AND i.type_desc = 'nonclustered'

AND i.is_primary_key = 0

AND i.is_unique_constraint = 0

AND (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id) > 10000

ORDER BY reads

 

 

Add comment


Security code
Refresh