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 :
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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)
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 ?
Partager