Saya menggunakan CTE rekursif berikut sebagai contoh minimal, tetapi secara umum, pengoptimal harus menggunakan kardinalitas 'tebakan' default untuk CTE rekursif:
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
*/
Perhatikan rows=31
perkiraan dan rows=5
kardinalitas aktual dalam rencana di atas. Dalam beberapa kasus 100 tampaknya digunakan sebagai perkiraan, saya tidak yakin logika yang tepat di balik tebakan.
Dalam masalah dunia nyata saya, perkiraan kardinalitas yang buruk mencegah rencana 'loop bersarang' yang cepat untuk dipilih. Bagaimana saya bisa 'mengisyaratkan' kardinalitas pengoptimal untuk CTE rekursif untuk mengatasi ini?
postgresql
postgresql-9.3
optimization
cte
Jack mengatakan coba topanswers.xyz
sumber
sumber
COST
fungsi, tapi tidak banyak lagi. Saya sarankan meningkatkannya di pgsql-hacker, tetapi Anda hanya akan terjebak dalam iterasi ke-9 dari debat "petunjuk", membuang-buang udara panas dan tidak mencapai apa-apa :-(Jawaban:
Saya telah mengatasi masalah seperti ini, tetapi saya berharap ada cara yang kurang menyenangkan:
sumber