jeudi 1 mars 2012

Analysez vos tables

D'abord, créons une table raisonnablement grosse, avec un bel index créé implicitement par la clé primaire.


drop table if exists numbers;
create table numbers(n integer primary key);
insert into numbers select generate_series(1, 100000);

Si l'on veut chercher une valeur en particulier, l'on voit que le planificateur de tâches décide très raisonnablement de passer par l'index:

select * from numbers where n = 1297



Là où ça devient intéressant, c'est lorsque l'on passe par une table temporaire, parce que l'on peut vouloir chercher par exemple plusieurs valeurs à la fois:

create temporary table test(n integer not null);
insert into test values(1297);

Regardons le plan...

select * from numbers n join test t on n.n = t.n;

Stupeur, le planificateur décide de hacher l'ensemble de la table "numbers", au lieu d'utiliser l'index.


En effet: le planificateur, ne connaissant pas la taille de la table temporaire, suppose par défaut qu'elle fait 1000 lignes, et par conséquent choisit un plan non optimal.

Heureusement, il est possible de lui demander d'analyser la table afin de mettre à jour ses statistiques.

Ansi:

analyze test;
select * from numbers n join test t on n.n = t.n;

nous donne enfin le plan recherché.


L'on peut ainsi dépenser quelques millisecondes au sein de la transaction pour mettre à jour ses statistiques, et sauver ainsi potentiellement plusieurs secondes en permettant au planificateur de mieux choisir.

2 commentaires:

Socrate a dit…

C'est quoi ton tool pour afficher tes plans d'execution joli comme cela

M87 a dit…

Il s'agit de pgAdmin, l'outil d'administration pour Postgres. Il est particulièrement puissant et complet. J'aimerais bien avoir quelque chose d'aussi pratique pour les autres SGBDR du marché!