Ich verwende den folgenden rekursiven CTE als minimales Beispiel, aber im Allgemeinen muss der Optimierer standardmäßige "erratene" Kardinalitäten für rekursive CTEs verwenden:
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
*/
Beachten Sie die rows=31
geschätzten und rows=5
tatsächlichen Kardinalitäten im obigen Plan. In einigen Fällen scheint 100 als Schätzung verwendet zu werden, ich bin mir nicht sicher, welche Logik hinter den Vermutungen steckt.
In meinem realen Problem verhindert die schlechte Kardinalitätsschätzung, dass ein schneller Plan für verschachtelte Schleifen ausgewählt wird. Wie kann ich die Kardinalität des Optimierers für einen rekursiven CTE andeuten, um dies zu umgehen?
COST
Funktionen, aber sonst nicht viel. Ich würde vorschlagen, es auf pgsql-Hacker zu bringen, aber Sie würden nur in die n-te Wiederholung der "Hinweise" -Debatte verwickelt sein, eine Menge heißer Luft verschwenden und nichts erreichen :-(