Accueil / Ressources / Date du dernier calcul des statistiques

› Script SQL

Date du dernier calcul des statistiques par objet.

Des statistiques périmées conduisent l'optimiseur à de mauvaises estimations, donc à de mauvais plans. Ce script indique, pour chaque statistique, quand elle a été calculée, sur quel échantillon, et combien de lignes ont été modifiées depuis.


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

À exécuter dans la base à analyser. La fonction sys.dm_db_stats_properties est disponible à partir de SQL Server 2008 R2 SP2 et de SQL Server 2012 SP1.

T-SQL
-- Statistiques des tables et vues indexées : dernier calcul, échantillon, modifications
-- À exécuter dans la base à analyser.
SET NOCOUNT ON;

DECLARE @JoursMin int = 0;     -- n'afficher que les statistiques plus anciennes que N jours

-- Réglages de la base
SELECT name                       AS base,
       is_auto_create_stats_on    AS creation_auto,
       is_auto_update_stats_on    AS maj_auto,
       is_auto_update_stats_async_on AS maj_auto_asynchrone
FROM sys.databases
WHERE database_id = DB_ID();

-- Une ligne par statistique
SELECT
    SCHEMA_NAME(o.schema_id)                               AS schema_nom,
    o.name                                                 AS objet,
    o.type_desc                                            AS type_objet,
    s.name                                                 AS statistique,
    s.auto_created                                         AS creee_auto,
    s.user_created                                         AS creee_par_utilisateur,
    s.no_recompute                                         AS sans_recalcul_auto,
    sp.last_updated                                        AS dernier_calcul,
    DATEDIFF(DAY, sp.last_updated, GETDATE())              AS jours_depuis_calcul,
    sp.rows                                                AS lignes,
    sp.rows_sampled                                        AS lignes_echantillon,
    CONVERT(decimal(6, 2), sp.rows_sampled * 100.0 / NULLIF(sp.rows, 0))        AS pct_echantillon,
    sp.modification_counter                                AS modifications_depuis,
    CONVERT(decimal(9, 2), sp.modification_counter * 100.0 / NULLIF(sp.rows, 0)) AS pct_lignes_modifiees
FROM sys.stats AS s
JOIN sys.objects AS o
     ON o.object_id = s.object_id
    AND o.is_ms_shipped = 0
    AND o.type IN ('U', 'V')
OUTER APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE ISNULL(DATEDIFF(DAY, sp.last_updated, GETDATE()), 99999) >= @JoursMin
ORDER BY sp.last_updated ASC;

Comment lire le résultat

  • dernier_calcul vide : la statistique n'a jamais été calculée (table vide ou index jamais utilisé).
  • pct_lignes_modifiees : le critère le plus parlant. Une table de plusieurs millions de lignes avec 20 % de lignes modifiées et un calcul ancien est une candidate immédiate.
  • pct_echantillon : un échantillon faible sur une grosse table peut donner de mauvaises estimations quand les données sont déséquilibrées. Un calcul avec balayage complet (WITH FULLSCAN) est alors à envisager.
  • sans_recalcul_auto : si la valeur est 1, SQL Server ne recalcule pas cette statistique automatiquement. Il faut une maintenance planifiée.

Mettre à jour

T-SQL
-- Une table, échantillon par défaut
UPDATE STATISTICS dbo.Commandes;

-- Une statistique précise, balayage complet
UPDATE STATISTICS dbo.Commandes IX_Commandes_ClientId WITH FULLSCAN;
  • Le recalcul automatique se déclenche après un seuil de modifications qui dépend de la taille de la table. Sur les grosses tables, ce seuil peut être trop élevé : une maintenance ciblée complète le dispositif.
  • Un recalcul invalide les plans en cache qui utilisent la table : prévoyez-le hors des pics de charge.
  • Reconstruire un index met déjà à jour ses statistiques avec un balayage complet. Inutile de les recalculer ensuite.

Un incident, un audit, une question ?

Un premier échange suffit à cadrer l'urgence et le périmètre.

Demander une intervention