2009-01-08 11 views
18

Ich frage mich, was die einfachste Weg, alle Indizes für alle Tabellen in einer Datenbank aufzulisten ist.Auflistung aller Indizes

Soll ich für jede Tabelle sp_helpindex aufrufen und die Ergebnisse in einer temporären Tabelle speichern, oder gibt es einen einfacheren Weg?

Kann jemand erklären, warum Einschränkungen in sysobjects gespeichert werden, aber Indizes nicht?

Antwort

6

könnten Sie sysindexes Referenz

Ein weiterer Trick, den Text von sp_helpindex zu suchen ist zu sehen, wie es Informationen aus den zugrunde liegenden Tabellen rekonstruiert.

sp_helptext 'sp_helpindex' 

Ich habe das nicht als Referenz für, aber ich glaube, Einschränkungen in sysobjects nicht gespeichert werden, weil sie eine andere Art der Sache sind; sysindexes enthält Metadaten zu Objekten in sysobjects.

4

Wenn Sie mehr Informationen benötigen, hier ist ein schöner SQL-Skript, das ich ab und zu verwenden:

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

Hier ist ein Beispiel für die Art der Abfrage ist Sie brauchen:

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 
; 

Dieser ist etwas spezifisch für einen bestimmten Zweck (ich benutze ihn in einer kleinen C# -App, um doppelte Indizes zu finden und die Ausgabe so zu formatieren, dass sie tatsächlich von einem Menschen lesbar ist). Aber Sie könnten es leicht an Ihre Bedürfnisse anpassen.

+0

Typ 2 ist nicht geclustert, irgendein Grund, warum Sie alle anderen Indextypen herausgefiltert haben? Die Frage erfordert es nicht. ref https://msdn.microsoft.com/en-us/library/ms173760%28v=sql.110%29.aspx –

-1

Die anderen Antworten sind SQL Server-spezifisch und verwenden sysobjects oder sys. * - Katalogansichten - Sie können auch die ISO-Standardansichten von INFORMATION_SCHEMA einsehen.

Diese werden über mehrere Datenbankanbieter hinweg unterstützt, z. SQL Server, MySQL, PostgreSQL und mehr. Die Sie sind höchstwahrscheinlich suchen, ist:

SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 

, die einzigartig, Primärschlüssel und Fremdschlüssel-Constraints werden auflisten - alles, was in einen Index auf SQL Server eingeschaltet wird.

+0

+1 für ANSI-Kompatibilität! –

+12

Die ANSI-Standard-Ansicht, 'INFORMATION_SCHEMA.TABLE_CONSTRAINTS' zeigt nicht regulären Indizes: es zeigt nur' CONSTRAINT_TYPE's von 'UNIQUE',' PRIMARY KEY', 'FREMD KEY' oder' check'. Siehe [das entsprechende Abschnitt Formular "SQL-99 vollständig, wirklich"] (https://mariadb.com/kb/en/sql-99-complete-really/16-sql-catalogs/the-information-schema/information_schema -views/informations_schematable_constraints /) –

3

Hier ist ein Skript, das SQL-Anweisungen zurückgibt, um alle Indizes in einer Datenbank neu zu erstellen.

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