Sto usando il seguente CTE ricorsivo come esempio minimo, ma in generale, l'ottimizzatore deve usare cardinalità "indovinate" predefinite per i CTE ricorsivi:
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
*/
Nota le cardinalità rows=31
stimate ed rows=5
effettive nel piano sopra. In alcuni casi 100 sembra essere usato come una stima, non sono sicuro della logica esatta dietro le ipotesi.
Nel mio problema del mondo reale, la scarsa stima della cardinalità sta impedendo la scelta di un piano rapido di "cicli annidati". Come posso 'suggerire' la cardinalità dell'ottimizzatore affinché un CTE ricorsivo possa aggirare il problema?
COST
sulle funzioni, ma non molto altro. Suggerirei di aumentarlo su pgsql-hacker, ma saresti rimasto coinvolto nell'ennesima iterazione del dibattito sui "suggerimenti", sprecando masse di aria calda e non ottenendo nulla :-(