See Also: [[wiki:Main Page|Main_Page]] - [[wiki:Transact SQL Code Library|Transact SQL Code Library]] - [[wiki:Index Related DMV Queries|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. Contents 1 Tutorial Video 1.1 T-SQL Code 2 Query Test Checklist 3 Changelog Tutorial Video In this short tutorial video, Brent Ozar explains how to use this code to tune your environment. http://tutorials.sqlserverpedia.com/SQLServerPedia-20090324-IndexTuning1.flv T-SQL Code 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 Query Test Checklist Works on SQL Server 2008: Yes Works on SQL Server 2005: Yes Works on SQL Server 2000: No. Unfortunately, there's no way to get this data for SQL Server 2000. Works on Standard Edition: Yes Works on case-sensitive servers: Yes Changelog 2009-07-04 - Brent Ozar - now filters out duplicate rows for partitioned tables.
↧