Estou usando a seguinte CTE recursiva como um exemplo mínimo, mas, em geral, o otimizador precisa usar cardinalidades 'adivinhadas' padrão para CTEs recursivas:
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
*/
Observe as cardinalidades rows=31
estimadas e rows=5
reais no plano acima. Em alguns casos, 100 parece ser usado como uma estimativa, não tenho certeza da lógica exata por trás das suposições.
No meu problema do mundo real, a fraca estimativa de cardinalidade está impedindo a escolha de um plano rápido de 'loops aninhados'. Como posso 'sugerir' a cardinalidade do otimizador para uma CTE recursiva contornar isso?
COST
funções, mas não muito mais. Eu sugiro aumentá-lo para pgsql-hackers, mas você seria pego na n-ésima iteração do debate "dicas", desperdiçando grandes quantidades de ar quente e sem conseguir nada :-(