T-SQL for finding Redundant Indexes

前端 未结 5 744
Happy的楠姐
Happy的楠姐 2020-12-03 12:51

Is anyone aware of a T-SQL script that can detect redundant indexes across an entire database? An example of a redundant index in a table would be as follows:



        
5条回答
  •  长情又很酷
    2020-12-03 13:34

    I created the following query that gives me a lot of good information to identify duplicate and near-duplicate indexes. It also includes other information like how many pages of memory an index takes, which allows me to give a higher priority to larger indexes. It shows what columns are indexed and what columns are included, so I can see if there are two indexes that are almost identical with only slight variations in the included columns.

    WITH IndexSummary AS
    (
    
    SELECT DISTINCT sys.objects.name AS [Table Name],
        sys.indexes.name AS [Index Name],
        SUBSTRING((SELECT ', ' +  sys.columns.Name as [text()]
            FROM sys.columns
                INNER JOIN sys.index_columns
                    ON sys.index_columns.column_id = sys.columns.column_id
                    AND sys.index_columns.object_id = sys.columns.object_id
            WHERE sys.index_columns.index_id = sys.indexes.index_id
                AND sys.index_columns.object_id = sys.indexes.object_id
                AND sys.index_columns.is_included_column = 0
            ORDER BY sys.columns.name
        FOR XML Path('')), 2, 10000) AS [Indexed Column Names],
        ISNULL(SUBSTRING((SELECT ', ' +  sys.columns.Name as [text()]
            FROM sys.columns
                INNER JOIN sys.index_columns
                ON sys.index_columns.column_id = sys.columns.column_id
                AND sys.index_columns.object_id = sys.columns.object_id
            WHERE sys.index_columns.index_id = sys.indexes.index_id
                AND sys.index_columns.object_id = sys.indexes.object_id
                AND sys.index_columns.is_included_column = 1
            ORDER BY sys.columns.name
            FOR XML Path('')), 2, 10000), '') AS [Included Column Names],
        sys.indexes.index_id, sys.indexes.object_id
    FROM sys.indexes
        INNER JOIN SYS.index_columns
            ON sys.indexes.index_id = SYS.index_columns.index_id
                AND sys.indexes.object_id = sys.index_columns.object_id
        INNER JOIN sys.objects
            ON sys.OBJECTS.object_id = SYS.indexES.object_id
    WHERE sys.objects.type = 'U'
    )
    
    SELECT IndexSummary.[Table Name],
        IndexSummary.[Index Name],
        IndexSummary.[Indexed Column Names],
        IndexSummary.[Included Column Names],
        PhysicalStats.page_count as [Page Count],
        CONVERT(decimal(18,2), PhysicalStats.page_count * 8 / 1024.0) AS [Size (MB)],
        CONVERT(decimal(18,2), PhysicalStats.avg_fragmentation_in_percent) AS [Fragment %]
    FROM IndexSummary
        INNER JOIN sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL)
           AS PhysicalStats
            ON PhysicalStats.index_id = IndexSummary.index_id
                AND PhysicalStats.object_id = IndexSummary.object_id
    WHERE (SELECT COUNT(*) as Computed
            FROM IndexSummary Summary2
            WHERE Summary2.[Table Name] = IndexSummary.[Table Name]
                AND Summary2.[Indexed Column Names] = IndexSummary.[Indexed Column Names]) > 1
    ORDER BY [Table Name], [Index Name], [Indexed Column Names], [Included Column Names]
    

    Results of the query look like this:

    Table Name  Index   Indexed Cols    Included Cols   Pages   Size (MB)   Frag %
    My_Table    Indx_1     Col1         Col2, Col3       123      0.96       8.94
    My_Table    Indx_2     Col1         Col2, Col3       123      0.96       8.94
    

    Complete Description

    For the complete explanation see Identifying Duplicate or Redundant Indexes in SQL Server.

提交回复
热议问题