My manager asked me to remove unused indexes in our OLTP database. I have two questions, is this really important and how can I tell?

Excellent questions…

Why remove unused indexes? Because you’re creating extra I/O operations keeping unused indexes around, and if [hopefully] you have maintenance plans ensuring you have up-to-date statistics and that clustered indexes are defragmented, you’re wasting precious time in your maintenance window.
How can you detect unused indexes? Well if you’re using SQL Server 2005, you can use the [sys].[dm_db_index_usage_stats] DMV.

The following query will return the indexes defined in a given database, sorted by the most frequently updated index to the least, and will highlight indexes that haven’t been used since the instance was last brought online:

select OBJECT_NAME(idx.[object_id]) "base table"
,CASE WHEN ist.[object_id] IS NULL THEN '!! UNUSED INDEX: ' ELSE '' END+ISNULL([name],'HEAP') "index name"
,idx.[index_id],[type_desc],[is_primary_key]
,ISNULL([user_updates],0) "user updates"
,ISNULL([user_seeks],0) "user seeks"
,ISNULL([user_scans],0) "user scans"
,ISNULL([user_lookups],0) "user lookups"
from [sys].[indexes] idx
left join [sys].[dm_db_index_usage_stats] ist
on idx.[object_id]=ist.[object_id]
and idx.[index_id]=ist.[index_id]
and ist.[database_id]=db_id()
order by [user_updates] desc, [user_seeks], [user_scans], [user_lookups]

Clearly, the longer your instance has been online, the more confident you can be that the unused indexes specified actually are not being used. Also, it’s imperative that you always remain aware that (for example) month-end, quarterly, semi-annual, etc jobs that might rely on some less frequently used indexes. Still, you don’t necessarily have to drop an unused index, especially if it’s been defined in a small table or if you’re not noticing slowdowns in application processing…but you might consider changing your maintenance jobs to focus on the most heavily-used indexes first.

5 Responses to “My manager asked me to remove unused indexes in our OLTP database. I have two questions, is this really important and how can I tell?”

  1. Jonathan Says:

    Hi,

    in your notes you mention this script identifies indexes that “haven’t been used since the instance was last brought online”. Is it possible to identify when the instance was last started and therefore how reliable these stats are?

    I know i could dig around in system log files somewhere or other but is it available through SSMS/TSQL?

    thanks

    Jonathan

  2. Ari Weil Says:

    Sure Jonathan, you absolutely can. By querying the sample_ms column in sys.dm_io_virtual_file_stats you can determine the number of milliseconds since the SQL Server instance started.

    FYI – a similar operation can be performed for SQL Server 2000 by using :fn_virtualfilestats or by querying sysprocesses for a system process like the lazy writer that comes online when the instance starts up.

  3. SQLServerPedia » Find overlapping indexes with ease in SQL Server 2005 Says:

    [...] a previous post I discussed how the SQL Server 2005 DMV [sys].[dm_db_index_usage_stats] could be used to find [...]

  4. vero Says:

    Hi

    I need view all de in index unused, but my SQL is 2000

    as I can see the indexes that are not used? which is the syntax?

  5. Ari Weil Says:

    In SQL Server 2000 you’d have to keep track of execution plans for your most important application SQL and compare any index scans/seeks against the indexes defined on your tables. There is no built-in mechanism to track this activity or assess the unused indexes in SQL Server 2000.

Leave a Reply