PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

एकाधिक जुड़ने का अनुकूलन

क्वेरी को ऑप्टिमाइज़ करते समय हमेशा 2 बातों का ध्यान रखना चाहिए:

  • किस इंडेक्स का उपयोग किया जा सकता है (आपको इंडेक्स बनाने की आवश्यकता हो सकती है)
  • क्वेरी कैसे लिखी जाती है (क्वेरी ऑप्टिमाइज़र को उपयुक्त इंडेक्स खोजने में सक्षम होने और डेटा को अनावश्यक रूप से दोबारा न पढ़ने के लिए आपको क्वेरी को बदलने की आवश्यकता हो सकती है)

कुछ अवलोकन:

  • आप अपनी तिथियों में शामिल होने से पहले तारीख में हेरफेर कर रहे हैं। एक सामान्य नियम के रूप में यह एक क्वेरी ऑप्टिमाइज़र को इंडेक्स का उपयोग करने से रोकेगा, भले ही वह मौजूद हो। आपको अपने भावों को इस प्रकार लिखने का प्रयास करना चाहिए कि अनुक्रमित स्तंभ व्यंजक के एक तरफ अपरिवर्तित रहें।

  • आपकी उपश्रेणियाँ उसी दिनांक सीमा तक फ़िल्टर कर रही हैं जैसे generate_series . यह एक दोहराव है, और यह सबसे कुशल अनुकूलन चुनने के लिए ऑप्टिमाइज़र की क्षमता को सीमित करता है। मुझे संदेह है कि प्रदर्शन में सुधार के लिए लिखा गया हो सकता है क्योंकि ऑप्टिमाइज़र दिनांक कॉलम (body_time पर एक इंडेक्स का उपयोग करने में असमर्थ था। )?

  • नोट :हम वास्तव में Body.body_time . पर एक इंडेक्स का उपयोग करना पसंद करेंगे

  • ORDER BY उपश्रेणियों के भीतर सबसे अच्छा बेमानी है। कम से कम यह क्वेरी ऑप्टिमाइज़र को शामिल होने से पहले परिणाम सेट को सॉर्ट करने के लिए मजबूर कर सकता है; और यह आवश्यक रूप से क्वेरी योजना के लिए अच्छा नहीं है। इसके बजाय केवल अंतिम प्रदर्शन के लिए अंत में ऑर्डरिंग लागू करें।

  • LEFT JOIN . का उपयोग आपके उपश्रेणियों में अनुचित है। मान लें कि आप NULL . के लिए ANSI कन्वेंशन का उपयोग कर रहे हैं व्यवहार (और आपको होना चाहिए), कोई भी बाहरी envelope . से जुड़ता है वापस आ जाएगा envelope_command=NULL , और इसके परिणामस्वरूप envelope_command=? . शर्त से इन्हें बाहर रखा जाएगा ।

  • सबक्वेरी o और i envelope_command . के लिए लगभग एक जैसे सेव हैं मूल्य। यह ऑप्टिमाइज़र को समान अंतर्निहित तालिकाओं को दो बार स्कैन करने के लिए बाध्य करता है। आप एक पिवट टेबल का उपयोग कर सकते हैं एक बार डेटा से जुड़ने और मानों को 2 कॉलम में विभाजित करने की तकनीक।

निम्नलिखित का प्रयास करें जो पिवट तकनीक का उपयोग करता है:

SELECT  p.period,
        /*The pivot technique in action...*/
        SUM(
        CASE WHEN envelope_command = 1 THEN body_size
        ELSE 0
        END) AS Outbound,
        SUM(
        CASE WHEN envelope_command = 2 THEN body_size
        ELSE 0
        END) AS Inbound
FROM    (
        SELECT  date '2009-10-01' + s.day AS period
        FROM    generate_series(0, date '2009-10-31' - date '2009-10-01') AS s(day)
        ) AS p 
        /*The left JOIN is justified to ensure ALL generated dates are returned
          Also: it joins to a subquery, else the JOIN to envelope _could_ exclude some generated dates*/
        LEFT OUTER JOIN (
        SELECT  b.body_size,
                b.body_time,
                e.envelope_command
        FROM    body AS b 
                INNER JOIN envelope e 
                  ON e.message_id = b.message_id 
        WHERE   envelope_command IN (1, 2)
        ) d
          /*The expressions below allow the optimser to use an index on body_time if 
            the statistics indicate it would be beneficial*/
          ON d.body_time >= p.period
         AND d.body_time < p.period + INTERVAL '1 DAY'
GROUP BY p.Period
ORDER BY p.Period

संपादित करें :टॉम एच द्वारा सुझाया गया जोड़ा गया फ़िल्टर।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres info_schema . का उपयोग करके कस्टम प्रकारों को कैसे सूचीबद्ध करें

  2. मुझे Postgresql docker image/container का उपयोग कैसे करना चाहिए?

  3. एक मॉड्यूल बनाकर डेटाबेस (psycopg2) के उपयोग को सरल बनाएं

  4. postgresql क्वेरी पर शून्य मान डालें

  5. PostgreSQL डेटाबेस संरचना को कैसे डंप करें (प्रत्येक ऑब्जेक्ट को अलग फ़ाइल में)