Używam następujących rekurencyjnych CTE jako minimalnego przykładu, ale ogólnie optymalizator musi używać domyślnych „zgadywanych” liczności dla rekurencyjnych 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
*/
Zanotuj rows=31
szacunkowe i rows=5
rzeczywiste liczności w powyższym planie. W niektórych przypadkach wartość 100 wydaje się być używana jako wartość szacunkowa, nie jestem pewien, czy dokładna logika kryje się za domysłami.
W moim prawdziwym problemie słabe oszacowanie liczności uniemożliwia wybór planu „zagnieżdżonych pętli”. Jak mogę „zasugerować” liczność optymalizatora dla rekurencyjnego CTE, aby obejść ten problem?
postgresql
postgresql-9.3
optimization
cte
Jack mówi, że spróbuj topanswers.xyz
źródło
źródło
COST
funkcje, ale niewiele więcej. Sugerowałbym podniesienie go na hakerów pgsql, ale wpadlibyście w n-tą iterację debaty „podpowiedzi”, marnując mnóstwo gorącego powietrza i nie osiągając niczego :-(Odpowiedzi:
Pracowałem nad takim problemem, ale mam nadzieję, że jest mniej nieprzyzwoity sposób:
źródło