2009-01-08 126 views
18

我在想什么最简单的方式列出数据库中所有表的所有索引是。列出所有索引

我应该为每个表调用sp_helpindex并将结果存储在临时表中,还是有更简单的方法?

任何人都可以解释为什么约束存储在sysobjects但索引不是?

回答

6

你可以参考sysindexes

另一个窍门是看的的sp_helpindex文,看看它是如何从底层表重建的信息。

sp_helptext 'sp_helpindex' 

我没有这方面的参考,但我相信约束不存储在sysobjects中,因为它们是不同类型的东西; sysindexes包含有关sysobjects中对象的元数据。

4

如果您需要了解更多信息,这里是一个很好的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 
33

这里有您需要的那种查询的一个例子:

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#应用​​程序中使用它来查找重复索引并对输出进行格式化,使其实际上可以被人类读取)。但是你可以很容易地适应你的需求。

+0

类型2是非聚集的,你有什么理由过滤掉了所有其他的索引类型?这个问题并不需要它。 ref https://msdn.microsoft.com/en-us/library/ms173760%28v=sql.110%29.aspx – 2015-06-08 14:26:44

-1

其他答案是特定于SQL Server,使用sysobjects或sys。*目录视图 - 您也可以参考ISO标准INFORMATION_SCHEMA视图。

这些支持多个数据库供应商,例如, SQL Server,MySQL,PostgreSQL等等。您最可能寻找的是:

SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 

这将列出唯一的主键和外键约束 - 所有变成SQL Server上的索引。

+0

+1兼容ANSI! – 2014-08-01 14:48:30

3

这是一个脚本,它将返回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 
相关问题