Aşağıdaki özyinelemeli CTE'yi en az örnek olarak kullanıyorum, ancak genel olarak, iyileştirici özyinelemeli CTE'ler için varsayılan 'tahmin edilen' kardinaliteleri kullanmak zorunda:
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
*/
Not rows=31
tahmin edilen ve rows=5
yukarıdaki planında gerçek kardinallikleri. Bazı durumlarda 100 tahmin olarak kullanılmış gibi görünüyor, tahminlerin ardındaki mantığın tam olarak ne olduğundan emin değilim.
Gerçek dünya sorunumda, zayıf kardinalite tahmini hızlı bir 'iç içe döngüler' planının seçilmesini engelliyor. Özyinelemeli bir CTE'nin bu soruna geçici bir çözüm bulması için en iyileştirici kardinalitesini nasıl 'ipucu' edebilirim?
COST
ama çok başka, fonksiyonları üzerine. Ben pgsql-hackerlar üzerinde yükseltmek öneriyoruz, ama sadece "ipuçları" tartışmanın nth yineleme, sıcak hava kütleleri israf ve hiçbir şey elde sıkışmış yakalanacaktı :-(