13.2. Statistiques utilisées par le planificateur
Comme nous avons vu dans la section précédente, le planificateur de
requêtes a besoin d'estimer le nombre de lignes récupérées par une
requête pour faire les bons choix dans ses plans de requêtes. Cette
section fournit un aperçu rapide sur les statistiques que le système
utilise pour ces estimations.
Un élément des statistiques est le nombre total d'entrées dans chaque
table et index, ainsi que le nombre de blocs disque occupés par
chaque table et index. Cette information est conservée dans la table
pg_class
sur les colonnes
reltuples
et
relpages
. Nous pouvons la
regarder avec des requêtes comme celle-ci :
SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname LIKE 'tenk1%';
relname | relkind | reltuples | relpages
----------------------+---------+-----------+----------
tenk1 | r | 10000 | 358
tenk1_hundred | i | 10000 | 30
tenk1_thous_tenthous | i | 10000 | 30
tenk1_unique1 | i | 10000 | 30
tenk1_unique2 | i | 10000 | 30
(5 rows)
Ici, nous pouvons voir que tenk1
contient 10000 lignes, comme pour ses index, mais que les index sont
bien plus petits que la table (ce qui n'est pas surprenant).
Pour des raisons d'efficacité,
reltuples
et
relpages
ne sont pas mis à jour en temps
réel, et du coup, elles contiennent habituellement des valeurs un peu
obsolètes. Elles sont mises à jour par les commandes
VACUUM
,
ANALYZE
et quelques commandes DDL
comme
CREATE INDEX
. Un
ANALYZE
seul, donc ne
faisant pas partie d'un
VACUUM
, génère une valeur
approximative de
reltuples
car
il ne lit pas chaque ligne de la table. Le planificateur mettra à
l'échelle les valeurs qu'il aura trouver dans pg_class pour correspondre à la taille physique
de la table, obtenant ainsi une approximation plus proche de la
réalité.
La plupart des requêtes ne récupère qu'une fraction des lignes dans
une table à cause de clauses WHERE qui
restreignent les lignes à examiner. Du coup, le planificateur a
besoin d'une estimation de la sélectivité
des clauses WHERE, c'est-à-dire la fraction
des lignes qui correspondent à chaque condition de la clause
WHERE. L'information utilisée pour cette
tâche est stockée dans le catalogue système
pg_statistic
. Les entrées de pg_statistic sont mises à jour par les commandes
ANALYZE
et
VACUUM ANALYZE
et sont toujours
approximatives même si elles ont été mises à jour récemment.
Plutôt que de regarder directement dans pg_statistic, il est mieux de visualiser sa vue
pg_stats lors de l'examen manuel des
statistiques. pg_stats est conçu pour
être plus facilement lisible. De plus, pg_stats est lisible par tous alors que
pg_statistic n'est lisible que par un
superutilisateur (ceci empêche les utilisateurs non privilégiés
d'apprendre certains choses sur le contenu des tables appartenant à
d'autres personnes à partir des statistiques. La vue pg_stats est restreinte pour afficher seulement
les lignes des tables lisibles par l'utilisateur courant). Par
exemple, nous pourrions lancer :
SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'road';
attname | n_distinct | most_common_vals
---------+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
name | -0.467008 | {"I- 580 Ramp","I- 880 Ramp","Sp Railroad ","I- 580 ","I- 680 Ramp","I- 80 Ramp","14th St ","5th St ","Mission Blvd","I- 880 "}
thepath | 20 | {"[(-122.089,37.71),(-122.0886,37.711)]"}
(2 rows)
pg_stats est décrit en détail dans la
Section 43.46, « pg_stats ».
Le nombre d'informations stockées dans pg_statistic, en particulier le nombre maximum
d'éléments dans les tableaux
most_common_vals
et
histogram_bounds
pour chaque colonne,
peut être initialisé sur une base colonne-par-colonne en utilisant la
commande
ALTER TABLE SET
STATISTICS
ou globalement en initialisant la variable
de configuration default_statistics_target.
La limite par défaut est actuellement de dix entrées. Augmenter la
limite pourrait permettre des estimations plus précises du
planificateur, en particulier pour les colonnes ayant des
distributions de données irrégulières, au prix d'un plus grand espace
consommé dans pg_statistic et en un
temps plus long pour calculer les estimations. En revanche, une
limite plus basse pourrait être appropriée pour les colonnes à
distributions de données simples.