我使用以下递归CTE作为最小示例,但总的来说,优化程序必须对递归CTE使用默认的“猜测”基数:
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
*/
注意上述计划中的rows=31
估计rows=5
基数和实际基数。在某些情况下,似乎使用100作为估算值,我不确定这些猜测背后的确切逻辑。
在我的现实世界问题中,基数估计不佳会阻止选择快速的“嵌套循环”计划。如何“提示”优化器基数,以便递归CTE可以解决此问题?
COST
功能,但没有其他。我建议在pgsql-hackers上提出,但是您只会陷入“提示”辩论的第n次迭代,浪费了大量的热气,却一无所获:-(