17
juillet
2012
Liste des index inutiles
juillet
2012
Voici une petite requête qui liste les index inutiles et présente la date de scrutation en sus des métadonnées des clauses de clef, INCLUDE et WHERE de composition de des index remontés comme inemployés.
WITH
TD AS (SELECT create_date AS DEPUIS
FROM sys.databases
WHERE database_id = DB_ID('tempdb')),
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 + '] ' + ord 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 + '] ' + ord
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),
dfj AS (SELECT dfi.object_id, dfi.index_id,
KEY_DEF AS KEY_COLUMNS,
COL_DEF AS INCLUDED_COLUMNS, i.filter_definition AS FILTER,
'CREATE INDEX [' + i.name + '] + ON [' + o.name +'].[' + s.name
+'] (' + KEY_DEF +')'
+ COALESCE(' INCLUDE (' + COL_DEF + ')', '')
+ COALESCE(' WHERE (' + i.filter_definition + ')', '') + ';' AS LOGICAL_DEFINITION
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 N = 1)
SELECT DEPUIS, s.name AS TABLE_SCHEMA, o.name AS TABLE_NAME, i.name AS INDEX_NAME,
user_seeks, user_scans, user_lookups, user_updates,
KEY_COLUMNS, INCLUDED_COLUMNS, FILTER, LOGICAL_DEFINITION
FROM sys.dm_db_index_usage_stats AS ius
CROSS JOIN TD
INNER JOIN sys.indexes AS i
ON ius.object_id = i.object_id
AND ius.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
LEFT OUTER JOIN dfj
ON dfj.object_id = i.object_id
AND dfj.index_id = i.index_id
WHERE database_id = DB_ID()
AND i.index_id > 1
AND user_seeks = 0
AND user_scans = 0
AND user_lookups = 0
AND is_unique = 0
AND is_primary_key = 0
AND is_unique_constraint = 0
ORDER BY user_updates, i.index_id DESC;
--------
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 * * * * *
Commentaires récents
- kahlabourri dans Une seule base de données ou plusieurs ?
- Zabriskir dans Recherches générique dans tous le code procédural de SQL Server
- SQLpro dans Où et comment sont stockées mes données avec PostGreSQL ?
- SQLpro dans Comparatif des fonctionnalités PostGreSQL 9.2 SQL Server 2012
- -kiki- dans MySQL ? Un SGBDR poudre aux yeux !
Archives
- avril 2013
- mars 2013
- février 2013
- octobre 2012
- août 2012
- juillet 2012
- juin 2012
- mai 2012
- avril 2012
- mars 2012
- février 2012
- janvier 2012
- décembre 2011
- novembre 2011
- octobre 2011
- septembre 2011
- août 2011
- juillet 2011
- juin 2011
- mai 2011
- avril 2011
- mars 2011
- février 2011
- janvier 2011
- novembre 2010
- octobre 2010
- septembre 2010
- août 2010
- juillet 2010
- mai 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- juillet 2009
- juin 2009
- mai 2009
- avril 2009
- mars 2009
- février 2009
- janvier 2009
- décembre 2008
- novembre 2008
- octobre 2008
- septembre 2008
- août 2008



Un article de SQLpro