2009-01-08 58 views
18

Tôi tự hỏi cách đơn giản nhất để liệt kê tất cả các chỉ mục cho tất cả các bảng trong cơ sở dữ liệu là gì.Liệt kê tất cả các chỉ mục

Tôi có nên gọi sp_helpindex cho mỗi bảng và lưu trữ kết quả trong bảng tạm thời không hoặc có cách nào dễ dàng hơn không?

Bất cứ ai có thể giải thích lý do tại sao các ràng buộc được lưu trữ trong sysobjects nhưng chỉ mục không?

Trả lời

6

Bạn có thể tham khảo sysindexes

Lừa khác là phải nhìn vào văn bản của sp_helpindex để xem nó như thế nào phục hồi lại thông tin từ các bảng cơ bản.

sp_helptext 'sp_helpindex' 

Tôi không có tham chiếu cho điều này, nhưng tôi tin rằng các ràng buộc không được lưu trữ trong sysobject vì chúng là một loại khác nhau; sysindexes chứa siêu dữ liệu về các đối tượng trong sysobjects.

4

Nếu bạn cần biết thêm thông tin, đây là một kịch bản SQL đẹp, mà tôi sử dụng bất cứ lúc nào:

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

Dưới đây là một ví dụ về các loại truy vấn mà bạn cần:

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 
; 

Điều này là một phần cụ thể cho một mục đích nhất định (tôi sử dụng nó trong một ứng dụng C# nhỏ để tìm chỉ mục trùng lặp và định dạng đầu ra để nó thực sự có thể đọc được bởi một con người). Nhưng bạn có thể dễ dàng điều chỉnh nó theo nhu cầu của bạn.

+0

loại 2 không được nhóm, bất kỳ lý do nào bạn đã lọc ra tất cả các loại chỉ mục khác? câu hỏi không yêu cầu nó. ref https://msdn.microsoft.com/en-us/library/ms173760%28v=sql.110%29.aspx –

-1

Các câu trả lời khác là SQL Server cụ thể, sử dụng chế độ xem sysobjects hoặc sys. * - bạn cũng có thể tham khảo chế độ xem chuẩn của tiêu chuẩn ISO INFORMATION_SCHEMA.

Chúng được hỗ trợ trên nhiều nhà cung cấp cơ sở dữ liệu, ví dụ: SQL Server, MySQL, PostgreSQL và hơn thế nữa. Người bạn có nhiều khả năng tìm kiếm nhất là:

SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 

sẽ liệt kê các ràng buộc chính, khóa chính và khóa ngoài - mọi thứ được biến thành chỉ mục trên SQL Server.

+0

+1 cho khả năng tương thích ANSI! –

+12

Chế độ xem chuẩn ANSI, 'INFORMATION_SCHEMA.TABLE_CONSTRAINTS' sẽ không hiển thị chỉ mục thông thường: chỉ hiển thị' CONSTRAINT_TYPE 'của' UNIQUE', 'PRIMARY KEY',' NGOẠI TỆ 'hoặc 'CHECK'. Xem [mẫu có liên quan "Hoàn thành, Thực sự"] (https://mariadb.com/kb/en/sql-99-complete-really/16-sql-catalogs/the-information-schema/information_schema -views/information_schematable_constraints /) –

3

Đây là tập lệnh sẽ trả về câu lệnh SQL để tạo lại tất cả các chỉ mục trong cơ sở dữ liệu.

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 
Các vấn đề liên quan