2010-08-19 10 views
5

बनाता है मैं एक प्रश्न है कि Postgres 8.4 पर के बारे में 5 सेकंड में चलाता है। यह एक दृश्य के कुछ अन्य तालिकाओं के लिए शामिल हो गए से डेटा का चयन करता है, लेकिन यह भी अंतराल() खिड़की समारोह, यानी उपयोग करता है।ध्यान में रखते हुए encapsulating Postgres क्वेरी यह बेहद धीमी गति से

SELECT *, lag(column1) OVER (PARTITION BY key1 ORDER BY ...), lag(...) 
FROM view1 v 
JOIN othertables USING (...) 
WHERE ... 

सुविधा के लिए मैं बस

SELECT *, lag(column1) OVER (PARTITION BY key1 ORDER BY ...), lag(...) 
FROM view1 v 

है और फिर उस से चयन करें, अन्य सभी जुड़ जाता है और पहले की तरह फिल्टर का उपयोग कर एक नया दृश्य बनाया। मेरे आश्चर्य के लिए यह क्वेरी 12 मिनट में पूरी नहीं होती है (मैंने इसे उस बिंदु पर रोक दिया)। स्पष्ट रूप से पोस्टग्रेस ने एक अलग निष्पादन योजना चुना है। मैं इसे ऐसा करने के लिए कैसे प्राप्त करूं, यानी। मूल प्रश्न के समान योजना का उपयोग करें? मैंने सोचा होगा कि एक दृश्य निष्पादन योजना को नहीं बदला जाना चाहिए, लेकिन स्पष्ट रूप से यह करता है।

संपादित करें: और क्या है, मैंने पाया कि अगर मैं पहले दृश्य की सामग्री को दूसरी बार में कॉपी करता हूं तो भी वापस नहीं आता है।

संपादित करें 2: ठीक है, मैं क्वेरी पर्याप्त योजनाओं पोस्ट करने के लिए आसान बना दिया है।

दृश्य (इस किसी भी उचित समय में वापस नहीं करता है) का उपयोग करना:

Subquery Scan sp (cost=5415201.23..5892463.97 rows=88382 width=370) 
    Filter: (((sp.ticker)::text ~~ 'Some Ticker'::text) AND (sp.price_date >= '2010-06-01'::date)) 
    -> WindowAgg (cost=5415201.23..5680347.20 rows=53029193 width=129) 
     -> Sort (cost=5415201.23..5441715.83 rows=53029193 width=129) 
       Sort Key: sp.stock_id, sp.price_date 
       -> Hash Join (cost=847.87..1465139.61 rows=53029193 width=129) 
        Hash Cond: (sp.stock_id = s.stock_id) 
        -> Seq Scan on stock_prices sp (cost=0.00..1079829.20 rows=53029401 width=115) 
        -> Hash (cost=744.56..744.56 rows=29519 width=18) 
          -> Seq Scan on stocks s (cost=0.00..744.56 rows=29519 width=18) 

दृश्य से बाहर खिड़की समारोह ले रहा है और स्वयं क्वेरी में डाल (यह तुरन्त रिटर्न):

WindowAgg (cost=34.91..34.95 rows=7 width=129) 
    -> Sort (cost=34.91..34.92 rows=7 width=129) 
     Sort Key: sp.stock_id, sp.price_date 
     -> Nested Loop (cost=0.00..34.89 rows=7 width=129) 
       -> Index Scan using stocks_ticker_unique on stocks s (cost=0.00..4.06 rows=1 width=18) 
        Index Cond: ((ticker)::text = 'Some Ticker'::text) 
        Filter: ((ticker)::text ~~ 'Some Ticker'::text) 
       -> Index Scan using stock_prices_id_date_idx on stock_prices sp (cost=0.00..30.79 rows=14 width=115) 
        Index Cond: ((sp.stock_id = s.stock_id) AND (sp.price_date >= '2010-06-01'::date)) 

तो यह है कि धीमी गति के मामले में यह पहले सभी डेटा को खिड़की समारोह लागू करने के लिए और फिर इसे फ़िल्टर करते हैं, जो शायद मुद्दा है कोशिश कर रहा है लगता है। मुझे नहीं पता कि यह क्यों कर रहा है, यद्यपि।

+0

+1, लेकिन मैं दृढ़ता से आप को भरने के लिए की आवश्यकता होगी संदेह '...' भागों से पहले कोई निदान कर सकते हैं क्या हो रहा है। – Edmund

+0

मैं कर सकता था, लेकिन अगर क्वेरी काफी जटिल है और मुझे यह समझा देना होगा कि सभी प्रासंगिक तालिकाओं की तरह क्या दिखता है। मेरा प्रश्न इस विशिष्ट प्रश्न के बजाय एक सामान्य समाधान के बारे में अधिक है: क्या पोस्टग्रेज़ को एक दृश्य को देखने के लिए कहने का एक तरीका है और उसी क्वेरी प्लान का उपयोग करें जैसे कि मैं अंतर्निहित एसक्यूएल सीधे दर्ज करूंगा। – EMP

+1

पोस्ट क्वेरी निष्पादन योजना? EXPLAIN SELECT ... –

उत्तर

2

दो योजनाओं के बीच आपका अंतर एक समग्र के साथ शामिल होने से आता है। यह एक नेस्टेड लूप योजना का उपयोग रोकता है। जब आप अपने विचार में कुल का उपयोग करते हैं, तो आप खुद को उस प्रतिकूल परिदृश्य में डाल देते हैं।

select foo.* 
from foo 
join (select bar.* from bar group by bar.field) as bar on foo.field = bar.field 
where ... 
order by bar.field 
limit 10; 
0

शायद आप एक दृश्य के बजाय एक Common Table Expression (CTE) उपयोग करने पर विचार कर सकता है:

यह, उदाहरण के लिए, लगभग हमेशा किसी मर्ज या हैश में शामिल होने की योजना के एक शीर्ष n प्रकार के बाद दो टेबल पर ले जाएगा । मैं एक दृश्य का उपयोग करने के लिए क्वेरी को स्पष्ट तरीके से बनाने में मदद कर सकता हूं, लेकिन उसी तरह निष्पादन योजना को प्रभावित नहीं करता है।

मैं this question में एक ऐसी ही समस्या थी और बदले में एक CTE का उपयोग कर के एक दृश्य के लिये कार्य योजना लागू और अधिक कुशल बना दिया।

संबंधित मुद्दे