Les requêtes de cette page lisent des informations de l'instance sans modifier vos données. Les commandes qui modifient quelque chose sont signalées dans le texte. Testez toujours sur un environnement non critique avant la production, et relisez chaque requête avant de l'exécuter.
Le script
-- Index utilisés uniquement en parcours (scans), jamais en recherche (seeks)
-- À exécuter dans la base à analyser. Droit requis : VIEW SERVER STATE.
SET NOCOUNT ON;
SELECT
SCHEMA_NAME(o.schema_id) AS schema_nom,
o.name AS table_nom,
i.name AS index_nom,
i.type_desc AS type_index,
n.nb_lignes AS lignes_table,
u.user_scans AS scans,
u.user_seeks AS seeks,
u.user_lookups AS lookups,
u.user_updates AS mises_a_jour,
u.last_user_scan AS dernier_scan,
CONVERT(decimal(18, 2), t.taille_mo) AS taille_mo
FROM sys.indexes AS i
JOIN sys.objects AS o
ON o.object_id = i.object_id
AND o.type = 'U'
AND o.is_ms_shipped = 0
JOIN sys.dm_db_index_usage_stats AS u
ON u.database_id = DB_ID()
AND u.object_id = i.object_id
AND u.index_id = i.index_id
CROSS APPLY (SELECT SUM(p.used_page_count) * 8 / 1024.0 AS taille_mo
FROM sys.dm_db_partition_stats AS p
WHERE p.object_id = i.object_id
AND p.index_id = i.index_id) AS t
CROSS APPLY (SELECT SUM(p.row_count) AS nb_lignes
FROM sys.dm_db_partition_stats AS p
WHERE p.object_id = i.object_id
AND p.index_id IN (0, 1)) AS n
WHERE i.index_id >= 1 -- exclut les tas (index_id = 0)
AND u.user_seeks = 0
AND u.user_scans > 0
ORDER BY u.user_scans DESC;Comment lire le résultat
- type_index CLUSTERED : un index clusterisé uniquement scanné correspond à une table lue en entier. C'est normal sur une petite table, préoccupant sur une grosse.
- lignes_table : un scan sur quelques centaines de lignes est sans conséquence. Concentrez-vous sur les tables de plusieurs centaines de milliers de lignes ou plus.
- mises_a_jour élevées avec peu de scans : l'index coûte plus qu'il ne sert.
Pistes d'amélioration
- Rechercher les requêtes qui scannent cet index (plan d'exécution) : leur prédicat est-il sargable, c'est-à-dire exploitable par une recherche ?
- Vérifier l'ordre des colonnes clés : la colonne la plus filtrée en égalité doit venir en premier.
- Détecter les conversions implicites de types et les fonctions appliquées aux colonnes filtrées, qui empêchent la recherche.
- Si l'index est utilisé comme index couvrant pour un rapport, un scan est acceptable : il peut alors être conservé, ou remplacé par un index columnstore pour de l'analytique.