web 2.0

SQL Server - Finding Redundant Indexes

Most of the time when there are performance problems in a database it is usually caused by the lack of an index. However, on the flip side, having too many indexes can also lead to problems. Every time you modify data in a table the associated indexes need to be updated. If you have a table with millions of rows and a large amount of indexes then DML statements will tend to cause a lot of unnecessary IO. In order to identify all the indexes in one of my SQL instances I developed this script. It basically iterates over every database and table in a instance and catalogs the name of each index and its associated metadata into a table:

SET NOCOUNT ON 

USE [DBA]
GO

IF  EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[IndexData]') AND type in (N'U'))
   DROP TABLE [dbo].[IndexData]
GO

CREATE TABLE [IndexData]
(
  database_name sysname collate database_default NOT NULL,
  table_name sysname collate database_default NOT NULL,
  index_name   sysname collate database_default NOT NULL,  
  description varchar(210) NULL,
    index_keys   nvarchar(2126) collate database_default NOT NULL
)
GO

CREATE TABLE ##indexes
(     
   index_name   sysname collate database_default NOT NULL,  
   description varchar(210) NULL,
   index_keys   nvarchar(2126) collate database_default NOT NULL
)  

DECLARE @sql nvarchar(4000)
SET @sql = 'USE [$]

      IF( ''$'' NOT IN ( ''tempdb'' ) ) BEGIN       
      
      exec  sp_msforeachtable ''truncate table ##indexes
           insert into ##indexes
                   EXEC sp_helpindex ''''?''''
      
                   insert into [DBA].[dbo].[IndexData]
                   select DB_NAME(db_id()), ''''?'''', index_name, description, index_keys from ##indexes''
      END'
                   
exec sp_msforeachdb @sql, @replacechar = '$'
                   
drop table ##indexes

select * from [DBA].[dbo].[IndexData]

The result of the script is a table called IndexData. It can easily be queried to find redundant indexes.  Here is an example:

select 
    * 
from 
    IndexData 
where 
    database_name = 'Northwind'
    and table_name = '[dbo].[Shippers]'
    and index_keys like '%SegmentID%'

The results (I modified the original northwind for test purposes)!

Tags: , ,

DBA | SQL

Comments are closed