postgres_fdw का प्रदर्शन धीमा है


12

एक विदेशी पर निम्नलिखित प्रश्न को 3.2 मिलियन पंक्तियों पर अमल करने में लगभग 5 सेकंड लगते हैं:

SELECT x."IncidentTypeCode", COUNT(x."IncidentTypeCode") 
FROM "IntterraNearRealTimeUnitReflexes300sForeign" x 
WHERE x."IncidentDateTime" >= '05/01/2016' 
GROUP BY x."IncidentTypeCode" 
ORDER BY 1;

जब मैं सामान्य टेबल पर उसी क्वेरी को निष्पादित करता हूं, तो यह 6 सेकंड में वापस आ जाती है। निष्पादन योजनाएं काफी अलग हैं:

सामान्य तालिका

Sort  (cost=226861.20..226861.21 rows=4 width=4) (actual time=646.447..646.448 rows=7 loops=1) 
  Sort Key: "IncidentTypeCode" 
  Sort Method: quicksort  Memory: 25kB 
  -> HashAggregate (cost=226861.12..226861.16 rows=4 width=4) (actual  time=646.433..646.434 rows=7 loops=1)
     Group Key: "IncidentTypeCode"
     -> Bitmap Heap Scan on "IntterraNearRealTimeUnitReflexes300s" x  (cost=10597.63..223318.41 rows=708542 width=4) (actual time=74.593..342.110 rows=709376 loops=1) 
        Recheck Cond: ("IncidentDateTime" >= '2016-05-01 00:00:00'::timestamp without time zone) 
        Rows Removed by Index Recheck: 12259 
        Heap Blocks: exact=27052 lossy=26888
        -> Bitmap Index Scan on idx_incident_date_time_300  (cost=0.00..10420.49 rows=708542 width=0) (actual time=69.722..69.722 rows=709376 loops=1) 
           Index Cond: ("IncidentDateTime" >= '2016-05-01 00:00:00'::timestamp without time zone) 

Planning time: 0.165 ms 
Execution time: 646.512 ms

विदेशी तालिका

Sort  (cost=241132.04..241132.05 rows=4 width=4) (actual time=4782.110..4782.112 rows=7 loops=1)   
  Sort Key: "IncidentTypeCode" 
  Sort Method: quicksort  Memory: 25kB
  -> HashAggregate  (cost=241131.96..241132.00 rows=4 width=4) (actual time=4782.097..4782.100 rows=7 loops=1)
     Group Key: "IncidentTypeCode"
     -> Foreign Scan on "IntterraNearRealTimeUnitReflexes300sForeign" x  (cost=10697.63..237589.25 rows=708542 width=4) (actual time=1.916..4476.946 rows=709376 loops=1) 

Planning time: 1.413 ms 
Execution time: 4782.660 ms

मुझे लगता है कि मैं GROUP BYक्लॉज के लिए एक उच्च कीमत चुका रहा हूं , जो कि विदेशी सर्वर के पास नहीं है जब मैं EXPLAIN VERBOSE:

SELECT
    "IncidentTypeCode"
FROM
    PUBLIC ."IntterraNearRealTimeUnitReflexes300s"
WHERE
    (
        (
            "IncidentDateTime" >= '2016-05-01 00:00:00' :: TIMESTAMP WITHOUT TIME ZONE
        )
    )

यह 700k पंक्तियों को लौटाता है। क्या इसके चारों ओर एक रास्ता है?

मैंने कल इस प्रलेखन पृष्ठ को पढ़ने में बहुत समय बिताया , और मुझे लगा कि मैंने अपना उत्तर use_remote_estimateसत्य के साथ सेट कर लिया है, लेकिन इसका कोई प्रभाव नहीं पड़ा।

यदि आवश्यक हो तो वस्तुओं को बनाने के लिए मेरे पास विदेशी सर्वर तक पहुंच है। WHEREक्लॉज में टाइमस्टैम्प का मूल्य कुछ भी हो सकता है; यह पूर्वनिर्धारित मूल्यों की सूची से नहीं आता है।


3
9.6 में कुछ पुशडाउन सुधार हैं जो ब्याज के हो सकते हैं: wiki.postgresql.org/wiki/NewIn96#postgres_fdw
जैक का कहना है कि topanswers.xyz

जब आप कहते हैं कि सामान्य बनाम विदेशी तालिका आप एक ही तालिका (स्थानीय और दूर से) या वास्तव में अलग-अलग तालिकाओं में चल रहे हैं (यह पढ़ता है जैसे कि वे हैं), यदि वे अलग-अलग चेक हैं तो दूरस्थ सर्वर पर अनुक्रमण सुनिश्चित करें कि वे समान हैं आप पूरी तरह से अलग जानकारी स्रोतों पढ़ने होना दिखाई देते हैं के रूप में IntterraNearRealTimeUnitReflexes300sForeignबनाम IntterraNearRealTimeUnitReflexes300sऔर idx_incident_date_time_300 मुझे लगता है 300s लोगों ही कर रहे हैं, लेकिन अगर इसके लायक जाँच हो सकता है idx_incident_date_time_300सूचकांक विदेशी सर्वर पर मौजूद है
Ste Bov

2
मैं जो समझता हूं, कुलियों (COUNT) को दूरस्थ सर्वर पर नहीं धकेला जाता है, जो लंबे अनुरोध के समय की व्याख्या करेगा। ऐसा लगता है कि यह सुविधा पृष्ठ 10 में दिखाई देगी - depesz.com/2016/10/25/…
जेरोम

@JeromeWAGNER - Awesome
J-DawG

जवाबों:


7

आप का उपयोग करते हैं use_remote_estimateहो सकता है यकीन है कि चलाने के लिए विश्लेषण विदेशी तालिका (मैं अनुमानों को देखने के बहुत करीब लौटे साथ, तो आप शायद यह किया था)। इसके अलावा, पुशडाउन सुधार <9.5 संस्करण में उपलब्ध नहीं हैं। मैं यह भी मानता हूं कि आपके पास दूरस्थ सर्वर पर एक ही तालिका संरचना है (सूचकांक सहित)। यदि कार्डिनिटी कम होने के कारण बिटमैप की आवश्यकता है, तो यह पुशडाउन तंत्र पर सीमाओं के कारण सूचकांक का उपयोग नहीं करेगा। आप BTREE इंडेक्स स्कैन ( टाइमस्टैम्प रेंज) को बाध्य करने के लिए लौटी हुई पंक्तियों की मात्रा को कम करना चाह सकते हैं)। दुर्भाग्य से, रिमोट सर्वर पर सेक्स्कैन से बचने का कोई साफ तरीका नहीं है यदि फ़िल्टर रिटर्न देता है + तालिका की पंक्तियों का 10% (यह प्रतिशत भिन्न हो सकता है यदि योजनाकार समझता है कि पूरी तालिका को स्कैन करना तलाश की तुलना में सस्ता है)। यदि आप SSD का उपयोग कर रहे हैं, तो आप संभवतः ट्वीक करने के लिए उपयोगी पाएंगे random_page_cost)।

ग्रुप बिहेव को अलग करने के लिए आप सीटीई का उपयोग कर सकते हैं:

WITH atable AS (
    SELECT "IncidentTypeCode"
    FROM PUBLIC ."IntterraNearRealTimeUnitReflexes300s"
    WHERE 
       ("IncidentDateTime" 
              BETWEEN '2016-05-01 00:00:00'::TIMESTAMP WITHOUT TIME ZONE 
                  AND '2016-05-02 00:00:00'::TIMESTAMP WITHOUT TIME ZONE)
)
SELECT atable."IncidentTypeCode", COUNT(atable.IncidentTypeCode) 
FROM atable
GROUP BY atable."IncidentTypeCode" 
ORDER BY atable."IncidentTypeCode";

1
CTE के उपयोग से प्रदर्शन समान था। हालांकि random_page_cost सेटिंग्स की कोशिश करेंगे। धन्यवाद!
J-DawG
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.