Composition logique d’un index

Voici une petite requête (récursive) pour connaître la définition logique de tous les index d’une base de données, pour MS SQL Server 2008 et suivant. Ille récupère la composition de la clé d’index ainsi que les éventuelles clauses INCLUDE et WHERE.

WITH  
idc AS (SELECT ic.object_id, index_id,  
               ROW_NUMBER() OVER(PARTITION BY ic.object_id, index_id, is_included_column
                                 ORDER BY index_column_id) AS index_column_id,
               is_included_column,  
               c.name, CASE WHEN is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END AS ord
        FROM   sys.index_columns AS ic
               INNER JOIN sys.COLUMNS AS c
                     ON ic.object_id = c.object_id
                        AND ic.column_id = c.column_id),
idk AS (SELECT object_id, index_id,  index_column_id, 1 AS cols,
               CAST('[' + name + '] ' + ord AS NVARCHAR(MAX)) AS KEY_DEF
        FROM   idc        
        WHERE  is_included_column = 0
          AND  index_column_id = 1
        UNION ALL
        SELECT idc.object_id, idc.index_id, idc.index_column_id, cols + 1,
               KEY_DEF + ', ' + '[' + idc.name + '] ' + ord
        FROM   idc
               INNER JOIN idk
                     ON idc.object_id = idk.object_id AND
                     idc.index_id = idk.index_id AND
                     idc.index_column_id = idk.index_column_id + 1
        WHERE  idc.is_included_column = 0),
idi AS (SELECT object_id, index_id,  index_column_id, 1 AS coli,
               CAST('[' + name + '] ' AS NVARCHAR(MAX)) AS COL_DEF
        FROM   idc        
        WHERE  is_included_column = 1
          AND  index_column_id = 1
        UNION ALL
        SELECT idc.object_id, idc.index_id, idc.index_column_id, coli + 1,
               COL_DEF + ', ' + '[' +  idc.name + '] '
        FROM   idc
               INNER JOIN idi
                     ON idc.object_id = idi.object_id AND
                     idc.index_id = idi.index_id AND
                     idc.index_column_id = idi.index_column_id + 1
        WHERE  idc.is_included_column = 1),
dfi AS (SELECT idk.*, COL_DEF,  
               ROW_NUMBER() OVER(PARTITION BY idk.object_id, idk.index_id  
                                 ORDER BY cols DESC) AS N
        FROM   idk
               LEFT OUTER JOIN idi
                    ON idk.object_id = idi.object_id
                       AND idk.index_id = idi.index_id)
SELECT 'CREATE '
       + CASE WHEN is_unique = 1 THEN ' UNIQUE ' ELSE '' END
       + CASE WHEN i.index_id = 1 THEN ' CLUSTERED ' ELSE '' END +
       ' INDEX [' + i.name + '] ON [' + s.name +'].[' + o.name
       +'] (' + KEY_DEF +')'  
       + COALESCE(' INCLUDE (' + COL_DEF + ')', '')
       + COALESCE(' WHERE (' + i.filter_definition + ')', '') + ';' AS LOGICAL_DEFINITION,
       is_unique, CASE WHEN i.index_id = 1 THEN 1 ELSE 0 END AS is_clustered
FROM   dfi
       INNER JOIN sys.indexes AS i
             ON dfi.object_id = i.object_id
                AND dfi.index_id = i.index_id
       INNER JOIN sys.objects AS o
             ON i.object_id = o.object_id
       INNER JOIN sys.schemas AS s
             ON o.schema_id = s.schema_id
WHERE  o."type" = 'U' AND N = 1;

--------
Frédéric Brouard, SQLpro - ARCHITECTE DE DONNÉES, http://sqlpro.developpez.com/
Expert bases de données relationnelles et langage SQL. MVP Microsoft SQL Server
www.sqlspot.com : modélisation, conseil, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence  * * * * *

MVP Microsoft SQL Server

Laisser un commentaire