Optimiseur / réécriture des requêtes et EXPLAIN
Bonjour
J'utilise Postgresql depuis peu. J'ai constaté sur ma base récemment installée un problème : l'optimiseur ne sait apparemment pas, quand c'est possible, simplifier une requête et la réécrire avant de l'exécuter. Exemple simple et reproductible :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
ma_bdd=# create table test (n numeric);
CREATE
ma_bdd=# insert into test values (1); --> lancé 10 fois
INSERT
ma_bdd=# insert into test values (0); --> lancé 10 fois
INSERT
ma_bdd=# select count(*) from test;
count
-------
20
(1 row)
ma_bdd=# vacuum full analyze test;
VACUUM
ma_bdd=# explain select * from test where n = 1;
QUERY PLAN
------------------------------------------------------
Seq Scan on test (cost=0.00..1.25 rows=10 width=9)
Filter: (n = 1::numeric)
(2 rows)
ma_bdd=# explain select * from test where n = 1 and n = 1;
QUERY PLAN
-----------------------------------------------------
Seq Scan on test (cost=0.00..1.30 rows=5 width=9)
Filter: ((n = 1::numeric) AND (n = 1::numeric))
(2 rows) |
En mettant "where n=1", l'optimiseur m'estime bien à 10 le nombre de lignes renvoyées, alors qu'en mettant "where n=1 and n=1", il m'estime à 5 (au lieu de 10 !), il a donc sous-estimé le nb de lignes renvoyées
L'optimiseur sait-il simplifier et réécrire une requête avant de l'exécuter ? Des paramétrages influent-ils au niveau du fichier postgresql.conf ou ailleurs ?
Ce problème m'embête grandement car à grande échelle des requêtes générées via BO peuvent contenir plusieurs fois la même condition (where n=1 and n=1 par exemple), et le fait que l'optimiseur sous-estime le nombre de lignes renvoyées me donne de mauvais plans d'exécutions lors de jointures complexes (utilisation de nested loop au lieu de hash join par exemple)
Quelqu'un aurait-il des explications sur ce comportement, et éventuellement une solution ?