代码之家  ›  专栏  ›  技术社区  ›  l15a

列出所有索引

  •  19
  • l15a  · 技术社区  · 16 年前

    我想知道 最简单的 列出数据库中所有表的所有索引的方法是。

    我应该打电话吗 sp_helpindex 对于每个表并将结果存储在临时表中,还是有更简单的方法?

    有谁能解释为什么约束存储在sysobjects中,而索引却没有?

    5 回复  |  直到 10 年前
        1
  •  34
  •   Eric Z Beard    16 年前

    下面是您需要的查询类型的示例:

    select 
        i.name as IndexName, 
        o.name as TableName, 
        ic.key_ordinal as ColumnOrder,
        ic.is_included_column as IsIncluded, 
        co.[name] as ColumnName
    from sys.indexes i 
    join sys.objects o on i.object_id = o.object_id
    join sys.index_columns ic on ic.object_id = i.object_id 
        and ic.index_id = i.index_id
    join sys.columns co on co.object_id = i.object_id 
        and co.column_id = ic.column_id
    where i.[type] = 2 
    and i.is_unique = 0 
    and i.is_primary_key = 0
    and o.[type] = 'U'
    --and ic.is_included_column = 0
    order by o.[name], i.[name], ic.is_included_column, ic.key_ordinal
    ;
    

    这一个有点特定于某个特定的目的(我在一个小的C#app中使用它来查找重复的索引并格式化输出,这样它实际上可以被人读取)。但你可以很容易地适应你的需要。

        2
  •  6
  •   Ed Guiness    16 年前

    你可以参考 sysindexes

    另一个技巧是查看sp_helpindex的文本,以了解它如何从底层表重建信息。

    sp_helptext 'sp_helpindex'
    

    我对此没有引用,但我相信约束不会存储在sysobjects中,因为它们是另一种类型的东西;sysindexes包含关于sysobjects中对象的元数据。

        3
  •  4
  •   splattne    16 年前

    如果您需要更多信息,这里有一个很好的SQL脚本,我经常使用它:

    DECLARE @TabName varchar(100)
    
    CREATE TABLE #temp (
       TabName varchar(200), IndexName varchar(200), IndexDescr varchar(200), 
       IndexKeys varchar(200), IndexSize int
    )
    
    DECLARE cur CURSOR FAST_FORWARD LOCAL FOR
        SELECT name FROM sysobjects WHERE xtype = 'U'
    
    OPEN cur
    
    FETCH NEXT FROM cur INTO @TabName
    WHILE @@FETCH_STATUS = 0
        BEGIN
            INSERT INTO #temp (IndexName, IndexDescr, IndexKeys)
            EXEC sp_helpindex @TabName
    
            UPDATE #temp SET TabName = @TabName WHERE TabName IS NULL
    
            FETCH NEXT FROM cur INTO @TabName
        END
    
    CLOSE cur
    DEALLOCATE cur
    
    DECLARE @ValueCoef int
    SELECT @ValueCoef = low FROM Master.dbo.spt_values WHERE number = 1 AND type = N'E'
    
    UPDATE #temp SET IndexSize = 
        ((CAST(sysindexes.used AS bigint) * @ValueCoef)/1024)/1024
            FROM sysobjects INNER JOIN sysindexes ON sysobjects.id = sysindexes.id
                INNER JOIN #temp T ON T.TabName = sysobjects.name AND T.IndexName = sysindexes.name
    
    SELECT * FROM #temp
    ORDER BY TabName, IndexName 
    
    DROP TABLE #temp
    
        4
  •  3
  •   Jon Wilson    7 年前

    下面是一个脚本,它将返回SQL语句来重新创建数据库中的所有索引。

    SELECT ' CREATE ' +
           CASE 
                WHEN I.is_unique = 1 THEN ' UNIQUE '
                ELSE ''
           END +
           I.type_desc COLLATE DATABASE_DEFAULT + ' INDEX ' +
           I.name + ' ON ' +
           SCHEMA_NAME(T.schema_id) + '.' + T.name + ' ( ' +
           KeyColumns + ' )  ' +
           ISNULL(' INCLUDE (' + IncludedColumns + ' ) ', '') +
           ISNULL(' WHERE  ' + I.filter_definition, '') + ' WITH ( ' +
           CASE 
                WHEN I.is_padded = 1 THEN ' PAD_INDEX = ON '
                ELSE ' PAD_INDEX = OFF '
           END + ',' +
           'FILLFACTOR = ' + CONVERT(
               CHAR(5),
               CASE 
                    WHEN I.fill_factor = 0 THEN 100
                    ELSE I.fill_factor
               END
           ) + ',' +
           -- default value 
           'SORT_IN_TEMPDB = OFF ' + ',' +
           CASE 
                WHEN I.ignore_dup_key = 1 THEN ' IGNORE_DUP_KEY = ON '
                ELSE ' IGNORE_DUP_KEY = OFF '
           END + ',' +
           CASE 
                WHEN ST.no_recompute = 0 THEN ' STATISTICS_NORECOMPUTE = OFF '
                ELSE ' STATISTICS_NORECOMPUTE = ON '
           END + ',' +
           ' ONLINE = OFF ' + ',' +
           CASE 
                WHEN I.allow_row_locks = 1 THEN ' ALLOW_ROW_LOCKS = ON '
                ELSE ' ALLOW_ROW_LOCKS = OFF '
           END + ',' +
           CASE 
                WHEN I.allow_page_locks = 1 THEN ' ALLOW_PAGE_LOCKS = ON '
                ELSE ' ALLOW_PAGE_LOCKS = OFF '
           END + ' ) ON [' +
           DS.name + ' ] ' +  CHAR(13) + CHAR(10) + ' GO' [CreateIndexScript]
    FROM   sys.indexes I
           JOIN sys.tables T
                ON  T.object_id = I.object_id
           JOIN sys.sysindexes SI
                ON  I.object_id = SI.id
                AND I.index_id = SI.indid
           JOIN (
                    SELECT *
                    FROM   (
                               SELECT IC2.object_id,
                                      IC2.index_id,
                                      STUFF(
                                          (
                                              SELECT ' , ' + C.name + CASE 
                                                                           WHEN MAX(CONVERT(INT, IC1.is_descending_key)) 
                                                                                = 1 THEN 
                                                                                ' DESC '
                                                                           ELSE 
                                                                                ' ASC '
                                                                      END
                                              FROM   sys.index_columns IC1
                                                     JOIN sys.columns C
                                                          ON  C.object_id = IC1.object_id
                                                          AND C.column_id = IC1.column_id
                                                          AND IC1.is_included_column = 
                                                              0
                                              WHERE  IC1.object_id = IC2.object_id
                                                     AND IC1.index_id = IC2.index_id
                                              GROUP BY
                                                     IC1.object_id,
                                                     C.name,
                                                     index_id
                                              ORDER BY
                                                     MAX(IC1.key_ordinal) 
                                                     FOR XML PATH('')
                                          ),
                                          1,
                                          2,
                                          ''
                                      ) KeyColumns
                               FROM   sys.index_columns IC2 
                                      --WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
                               GROUP BY
                                      IC2.object_id,
                                      IC2.index_id
                           ) tmp3
                )tmp4
                ON  I.object_id = tmp4.object_id
                AND I.Index_id = tmp4.index_id
           JOIN sys.stats ST
                ON  ST.object_id = I.object_id
                AND ST.stats_id = I.index_id
           JOIN sys.data_spaces DS
                ON  I.data_space_id = DS.data_space_id
           JOIN sys.filegroups FG
                ON  I.data_space_id = FG.data_space_id
           LEFT JOIN (
                    SELECT *
                    FROM   (
                               SELECT IC2.object_id,
                                      IC2.index_id,
                                      STUFF(
                                          (
                                              SELECT ' , ' + C.name
                                              FROM   sys.index_columns IC1
                                                     JOIN sys.columns C
                                                          ON  C.object_id = IC1.object_id
                                                          AND C.column_id = IC1.column_id
                                                          AND IC1.is_included_column = 
                                                              1
                                              WHERE  IC1.object_id = IC2.object_id
                                                     AND IC1.index_id = IC2.index_id
                                              GROUP BY
                                                     IC1.object_id,
                                                     C.name,
                                                     index_id 
                                                     FOR XML PATH('')
                                          ),
                                          1,
                                          2,
                                          ''
                                      ) IncludedColumns
                               FROM   sys.index_columns IC2 
                                      --WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
                               GROUP BY
                                      IC2.object_id,
                                      IC2.index_id
                           ) tmp1
                    WHERE  IncludedColumns IS NOT NULL
                ) tmp2
                ON  tmp2.object_id = I.object_id
                AND tmp2.index_id = I.index_id
    WHERE  I.is_primary_key = 0
           AND I.is_unique_constraint = 0
           --AND T.name NOT LIKE 'mt_%'
           --AND I.name NOT LIKE 'mt_%'
               --AND I.Object_id = object_id('Person.Address') --Comment for all tables
               --AND I.name = 'IX_Address_PostalCode' --comment for all indexes 
    
        5
  •  0
  •   Stephen Rauch Madhusudan Sharma    6 年前

    我不清楚为什么索引不存储在sys.objects中。但是,我希望找到一种简单的方法来列出数据库中所有表和视图的所有索引。以下查询检索所有索引,包括其类型、对象id和对象类型。

    use /*Enter here your database*/
    go
    select A.Object_id,B.name,B.type,B.type_desc, A.index_id,A.type,A.type_desc
    from sys.indexes A left join sys.objects B on A.object_id=B.object_id
    where B.type = 'U' or B.type='V' /*filtering on U or V to retrieve tables and views only*/
    order by B.name ASC /*Optional sorting*/