J'utilise le CTE récursif suivant comme exemple minimal, mais en général, l'optimiseur doit utiliser les cardinalités «devinées» par défaut pour les CTE récursifs:
with recursive w(n) as ( select 1 union all select n+1 from w where n<5 ) select * from w;
/*
n
---
1
2
3
4
5
*/
explain analyze
with recursive w(n) as ( select 1 union all select n+1 from w where n<5 ) select * from w;
/*
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
CTE Scan on w (cost=2.95..3.57 rows=31 width=4) (actual time=0.005..0.020 rows=5 loops=1)
CTE w
-> Recursive Union (cost=0.00..2.95 rows=31 width=4) (actual time=0.003..0.017 rows=5 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
-> WorkTable Scan on w w_1 (cost=0.00..0.23 rows=3 width=4) (actual time=0.002..0.002 rows=1 loops=5)
Filter: (n < 5)
Rows Removed by Filter: 0
*/
Notez les cardinalités rows=31
estimées et rows=5
réelles dans le plan ci-dessus. Dans certains cas, 100 semble être utilisé comme estimation, je ne suis pas sûr de la logique exacte derrière les suppositions.
Dans mon problème réel, la mauvaise estimation de la cardinalité empêche le choix d'un plan rapide de «boucles imbriquées». Comment puis-je «suggérer» la cardinalité de l'optimiseur pour un CTE récursif pour contourner ce problème?
COST
fonctions, mais pas grand-chose d'autre. Je suggérerais de le soulever sur pgsql-hackers, mais vous vous retrouveriez juste pris dans la nième itération du débat sur les "indices", gaspillant des masses d'air chaud et n'obtenant rien :-(