Statistiques pour le planificateur

Module M6

Dalibo SCOP

25.03.1

mars 2025

Sur ce document

Formation Module M6
Titre Statistiques pour le planificateur
Révision 25.03.1
PDF https://dali.bo/m6_pdf
EPUB https://dali.bo/m6_epub
HTML https://dali.bo/m6_html
Slides https://dali.bo/m6_slides
TP https://dali.bo/m6_tp
TP (solutions) https://dali.bo/m6_solutions

Licence Creative Commons CC-BY-NC-SA

Cette formation est sous licence CC-BY-NC-SA. Vous êtes libre de la redistribuer et/ou modifier aux conditions suivantes :

  • Paternité
  • Pas d’utilisation commerciale
  • Partage des conditions initiales à l’identique

Marques déposées

PostgreSQL® Postgres® et le logo Slonik sont des marques déposées par PostgreSQL Community Association of Canada.

Versions de PostgreSQL couvertes

Ce document ne couvre que les versions supportées de PostgreSQL au moment de sa rédaction, soit les versions 13 à 17.

Statistiques pour le planificateur

PostgreSQL

Introduction

  • Indispensables !
  • Statistiques sur les données pour le planificateur
    • pour le choix du parcours
    • comme le choix des jointures
  • Les statistiques indiquent :
    • la cardinalité d’un filtre → stratégie d’accès
    • la cardinalité d’une jointure → algorithme de jointure
    • la cardinalité d’un regroupement → algorithme de regroupement
  • Sans bonnes statistiques, pas de bons plans !

Au menu

  • Statistiques de volumétrie
  • Statistiques sur les données
    • principe
    • statistiques étendues
  • ANALYZE et autovacuum

Statistiques de volumétrie

pg_class

SELECT relpages, reltuples FROM pg_class WHERE relname = "employes";
  • pour tables et index
  • relpages : taille en blocs
    • dont relallvisible
  • reltuples : lignes
  • Mise à jour : VACUUM/ANALYZE

Statistiques sur les données

Tables de statistiques

  • Échantillonner pour mieux planifier
  • Estimer la sélectivité d’une clause WHERE ou JOIN
  • Tables pg_statistic (par colonne), pg_statistic_ext
  • Vues pg_stats (par colonne), pg_stats_ext et pg_stats_ext_exprs

Statistiques monovariées

Statistiques monovariées

  • Pour chaque colonne de chaque table
  • Adaptées à la majorité des cas
    • forte ou faible contrainte de type
    • forte ou faible variabilité des données
  • Calculées automatiquement par ANALYZE

Valeurs distincts (N-Distinct)

-[ RECORD 1 ]----------+-----------------------------------------------
schemaname             | public
tablename              | employes
attname                | date_embauche
n_distinct             | -0.5
  • Estimation basée sur l’échantillon
  • Si > 0 : nombre de valeurs distinctes dans la colonne
    • constant indépendamment de la volumétrie
  • Si < 0 : nombre de valeurs distinctes / nombre de lignes × -1
    • proportionnel à la volumétrie
  • -1 : toutes les valeurs diffèrent (ex : PK)
  • La valeur peut être forcée

Most Common Values (MCV)

-[ RECORD 1 ]-----+----------------------------------------------------
schemaname        | public
tablename         | employes
attname           | date_embauche
most_common_vals  | {2006-03-01,2006-09-01,2000-06-01,2005-03-06,2006-01-01}
most_common_freqs | {0.214286,0.214286,0.142857,0.142857,0.142857}
  • Liste des valeurs les plus fréquentes
  • Liste des fréquences de ces valeurs
  • Variable en fonction de l’échantillonnage

Histogramme

-[ RECORD 1 ]-------+------------------------------------------------------
schemaname          | public
tablename           | produits
attname             | prix
histogram_bounds    | {4.00,6.12,9.14,23.55,99.57}
  • Décrit la répartition des données (hors MCV et NULL)
  • Nombre de lignes sensiblement égal entre chaque borne de l’histogramme
  • N’est pas calculé par ANALYZE si toutes les valeurs sont dans les MCV

Valeurs nulles

-[ RECORD 1 ]----------+-----------------------------------------------
schemaname             | public
tablename              | clients
attname                | telephone_fixe
null_frac              | 0.98
  • Estimation du nombre de valeur nulles dans la colonne

Corrélation physique

-[ RECORD 1 ]----------+-----------------------------------------------
schemaname             | public
tablename              | clients
attname                | date_inscription
correlation            | 1
  • Varie de -1 à 1
  • Indique si les données sont ordonnées dans les fichiers
  • Arbitre la pertinence de l’usage d’un index
    • forte corrélation = peu de blocs à lire
    • faible corrélation = données dispersées

Largeur moyenne des données

-[ RECORD 1 ]----------+-----------------------------------------------
schemaname             | public
tablename              | employes
attname                | date_embauche
avg_width              | 4
  • Calculé pour les champs non NULL de taille variable (text, json, jsonb, binaires, etc.)
  • Constant pour les autres types (integer, boolean, char, etc.)

Échantillonnage

Taille de l’échantillon

  • Échantillon de 30 000 lignes par défaut
    • default_statistics_target = 100
    • × 300 lignes

Modifier l’échantillon

-- Configurable pour chaque colonne
ALTER TABLE t ALTER COLUMN c SET STATISTICS 300 ;
-- Configurable pour chaque statistique étendue 
ALTER STATISTICS nom SET STATISTICS valeur ;
  • Échantillon plus important
    • plus précis dans certains cas
    • temps de planification plus long
  • ANALYZE pour rafraîchir les statistiques

Statistiques multivariées

Statistiques multivariées

  • Pas par défaut
  • CREATE STATISTICS
  • Trois types de statistiques
    • nombre de valeurs distinctes
    • dépendances fonctionnelles
    • liste MCV
  • ANALYZE après la création
  • vue pg_stat_ext

Dépendances fonctionnelles

CREATE STATISTICS stat_services (dependencies)
  ON code_postal, ville, departement
  FROM services;
  • Indique une dépendance fonctionnelle entre deux colonnes
  • La valeur d’une colonne varie en fonction d’une autre

Valeurs distinctes (N-Distinct)

CREATE STATISTICS stat_services (ndistinct)
  ON couleur, cépage
  FROM vins;
  • Indique que plusieurs colonnes sont liées
  • Utile pour les clauses GROUP BY

Most Common Values (MCV)

CREATE STATISTICS stat_services (mcv)
  ON couleur, cépage
  FROM vins;
  • Même principe que pour une seule colonne
  • Supporte les opérateurs d’inégalité >,>,<= et >=

Statistiques étendues

Statistiques sur les expressions

CREATE STATISTICS employe_big_extract
ON extract('year' FROM date_embauche) FROM employes_big;
  • Pas créées par défaut
  • Résout le problème des statistiques difficiles à estimer
  • À partir de la v14 (index fonctionnel nécessaire avant)
  • ANALYZE après la création
  • Vue pg_stat_ext_exprs

Catalogues pour les statistiques étendues

Vues disponibles :

  • pg_stats_ext
  • pg_stats_ext_exprs (pour les expressions, v14)

Collecte des statistiques

Quand collecter les statistiques ?

  • À la demande
    • ANALYZE
    • VACUUM ANALYZE
    • vacuumdb --analyze / --analyze-only
  • Automatiquement
    • processus autovacuum
    • paramètres autovacuum_analyze_*
  • Suivi :
    • pg_stat_user_tables

ANALYZE

ANALYZE; -- base entière
ANALYZE pgbench_tellers; -- une table
ANALYZE pgbench_accounts (abalance) ; -- une colonne
  • Un échantillon de table → statistiques
  • Table vide : conserve les anciennes statistiques
  • Nouvelle table : valeur par défaut

Fréquence d’analyse

  • Dépend principalement de la fréquence des requêtes DML
  • Le processus autovacuum fait l’ANALYZE mais…
    • pas sur les tables temporaires
    • pas assez rapidement parfois
  • Planification au niveau système avec cron
    • psql -c "ANALYZE"
    • ou vacuumdb --analyze-only

Problèmes les plus courants

  • Statistiques obsolètes
  • Opérations ponctuelles (batch, import de données)
  • Dépendances fonctionnelles

Statistiques obsolètes

Les statistiques sont-elles à jour ?

  • Traitement lourd
    • faire tout de suite ANALYZE
  • Table trop grosse
    • régler l’échantillonnage
    • régler l’autovacuum sur cette table
  • Retard de mise à jour suite à crash ou restauration

Colonnes corrélées

SELECT * FROM corr1 WHERE c1=1 AND c2=1
  • Si c1 = 1 pour 20 % des lignes
  • et c2 = 2 pour 10 % des lignes
  • Alors le planificateur calcule : 2 % des lignes (20 % × 10 %)
    • Mais en réalité ?
  • Pour corriger :
CREATE STATISTICS corr1_c1_c2 ON c1,c2 FROM corr1 ;

Conclusion

  • Un échantillonnage des données très efficace…
  • …mais pas parfait !
  • Il faut bien comprendre son fonctionnement
  • Possibilité d’ajuster la collecte des statistiques si besoin

Références

Questions

N’hésitez pas, c’est le moment !

Quiz

Travaux pratiques

Préambule

Vue pg_stats

Corrélation entre colonnes

Travaux pratiques (solutions)