मैं निम्नलिखित पुनरावर्ती 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- हैकर्स पर बढ़ाने का सुझाव देता हूं, लेकिन आप "संकेत" बहस के n'th पुनरावृत्ति में फंस जाएंगे, गर्म हवा के द्रव्यमान को बर्बाद कर रहे हैं और कुछ भी हासिल नहीं करेंगे :-(