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

प्रत्येक ग्रुप बाय ग्रुप में पहली पंक्ति का चयन करें?

DISTINCT ON PostgreSQL . में इसके लिए आम तौर पर सबसे सरल और तेज़ है .
(कुछ कार्यभार के प्रदर्शन अनुकूलन के लिए नीचे देखें।)

SELECT DISTINCT ON (customer)
       id, customer, total
FROM   purchases
ORDER  BY customer, total DESC, id;

या छोटा (यदि उतना स्पष्ट नहीं है) आउटपुट कॉलम की क्रमिक संख्या के साथ:

SELECT DISTINCT ON (2)
       id, customer, total
FROM   purchases
ORDER  BY 2, 3 DESC, 1;

अगर total न्यूल हो सकता है (किसी भी तरह से चोट नहीं पहुंचाएगा, लेकिन आप मौजूदा इंडेक्स से मेल खाना चाहेंगे):

...
ORDER  BY customer, total DESC NULLS LAST, id;

प्रमुख बिंदु

DISTINCT ON मानक का एक PostgreSQL एक्सटेंशन है (जहां केवल DISTINCT संपूर्ण SELECT . पर सूची परिभाषित है)।

DISTINCT ON . में कितने भी भाव सूचीबद्ध करें खंड, संयुक्त पंक्ति मान डुप्लिकेट को परिभाषित करता है। मैनुअल:

<ब्लॉकक्वॉट>

जाहिर है, दो पंक्तियों को अलग माना जाता है यदि वे कम से कम एक कॉलम मान में भिन्न हों। इस तुलना में शून्य मान समान माने जाते हैं।

बोल्ड जोर मेरा।

DISTINCT ON के साथ जोड़ा जा सकता है ORDER BY . ORDER BY . में प्रमुख भाव DISTINCT ON . में एक्सप्रेशन के सेट में होना चाहिए , लेकिन आप उन लोगों के बीच स्वतंत्र रूप से ऑर्डर पुनर्व्यवस्थित कर सकते हैं। उदाहरण।
आप अतिरिक्त जोड़ सकते हैं ORDER BY . के भाव साथियों के प्रत्येक समूह से एक विशेष पंक्ति लेने के लिए। या, जैसा कि मैनुअल कहता है:

<ब्लॉकक्वॉट>

DISTINCT ON अभिव्यक्ति (ओं) को सबसे बाईं ओर ORDER BY . से मेल खाना चाहिए अभिव्यक्ति (ओं)। ORDER BY क्लॉज में आम तौर पर अतिरिक्त एक्सप्रेशन होते हैं जो प्रत्येक DISTINCT ON के भीतर पंक्तियों की वांछित प्राथमिकता निर्धारित करते हैं समूह।

मैंने id जोड़ा संबंधों को तोड़ने के लिए अंतिम आइटम के रूप में:
"सबसे छोटी id वाली पंक्ति चुनें उच्चतम total sharing साझा करने वाले प्रत्येक समूह से ।"

परिणामों को इस तरह से ऑर्डर करने के लिए जो पहले प्रति समूह को निर्धारित करने वाले सॉर्ट ऑर्डर से असहमत हो, आप ऊपर की क्वेरी को किसी अन्य ORDER BY के साथ एक बाहरी क्वेरी में नेस्ट कर सकते हैं। . उदाहरण।

अगर total NULL हो सकता है, आप संभवतः सबसे बड़ी गैर-शून्य मान वाली पंक्ति चाहते हैं। जोड़ें NULLS LAST जैसे दिखाया। देखें:

  • कॉलम ASC के अनुसार क्रमित करें, लेकिन NULL मान पहले?

SELECT सूची DISTINCT ON . में भावों से विवश नहीं है या ORDER BY किसी भी तरह से। (उपरोक्त साधारण मामले में आवश्यक नहीं):

  • आपको यह नहीं करना है DISTINCT ON . में किसी भी भाव को शामिल करें या ORDER BY

  • आप कर सकते हैं SELECT . में कोई अन्य व्यंजक शामिल करें सूची। यह बहुत अधिक जटिल प्रश्नों को सबक्वेरी और एग्रीगेट / विंडो फ़ंक्शंस के साथ बदलने के लिए महत्वपूर्ण है।

मैंने पोस्टग्रेज़ संस्करण 8.3 - 13 के साथ परीक्षण किया। लेकिन यह सुविधा कम से कम संस्करण 7.1 के बाद से है, इसलिए मूल रूप से हमेशा।

सूचकांक

उत्तम उपरोक्त क्वेरी के लिए अनुक्रमणिका एक बहु-स्तंभ अनुक्रमणिका होगी जो मिलान क्रम में और मिलान क्रम के साथ सभी तीन स्तंभों में फैली होगी:

CREATE INDEX purchases_3c_idx ON purchases (customer, total DESC, id);

अति विशिष्ट हो सकता है। लेकिन इसका उपयोग करें यदि किसी विशेष क्वेरी के लिए प्रदर्शन पढ़ना महत्वपूर्ण है। अगर आपके पास DESC NULLS LAST है क्वेरी में, इंडेक्स में उसी का उपयोग करें ताकि सॉर्ट ऑर्डर मैच हो और इंडेक्स लागू हो।

प्रभावकारिता / प्रदर्शन अनुकूलन

प्रत्येक क्वेरी के लिए अनुरूप अनुक्रमणिका बनाने से पहले लागत और लाभ को तौलें। उपरोक्त सूचकांक की क्षमता काफी हद तक डेटा वितरण . पर निर्भर करती है ।

अनुक्रमणिका का उपयोग किया जाता है क्योंकि यह पूर्व-क्रमबद्ध डेटा वितरित करता है। Postgres 9.2 या बाद के संस्करण में क्वेरी केवल अनुक्रमणिका स्कैन . से भी लाभान्वित हो सकती है यदि सूचकांक अंतर्निहित तालिका से छोटा है। हालांकि, इंडेक्स को पूरी तरह से स्कैन करना होगा।

कुछ के लिए प्रति ग्राहक पंक्तियाँ (स्तंभ में उच्च कार्डिनैलिटी customer ), यह बहुत ही कुशल है। इससे भी अधिक यदि आपको वैसे भी सॉर्ट किए गए आउटपुट की आवश्यकता है। प्रति ग्राहक पंक्तियों की बढ़ती संख्या के साथ लाभ सिकुड़ता है।
आदर्श रूप से, आपके पास पर्याप्त work_mem है रैम में शामिल सॉर्ट स्टेप को प्रोसेस करने के लिए और डिस्क पर स्पिल नहीं करने के लिए। लेकिन आम तौर पर work_mem सेट करना भी उच्च प्रतिकूल प्रभाव डाल सकता है। SET LOCAL . पर विचार करें असाधारण रूप से बड़े प्रश्नों के लिए। EXPLAIN ANALYZE . के साथ पता लगाएं कि आपको कितना चाहिए . "डिस्क: . का उल्लेख करें " सॉर्ट चरण में और अधिक की आवश्यकता को इंगित करता है:

  • लिनक्स पर PostgreSQL में कॉन्फ़िगरेशन पैरामीटर work_mem
  • दिनांक और टेक्स्ट के अनुसार ORDER का उपयोग करके सरल क्वेरी को अनुकूलित करें

कईके लिए प्रति ग्राहक पंक्तियाँ (स्तंभ में कम कार्डिनैलिटी customer ), एक ढीली अनुक्रमणिका स्कैन (a.k.a. "स्किप स्कैन") (बहुत) अधिक कुशल होगा, लेकिन इसे पोस्टग्रेज 14 तक लागू नहीं किया गया है। (केवल-इंडेक्स स्कैन के लिए एक कार्यान्वयन पोस्टग्रेज 15 के लिए विकास में है। यहां और यहां देखें।)
के लिए अब, तेज़ क्वेरी तकनीक हैं इसके स्थानापन्न करने के लिए। विशेष रूप से यदि आपके पास अद्वितीय ग्राहकों को रखने वाली एक अलग तालिका है, जो कि विशिष्ट उपयोग का मामला है। लेकिन यह भी अगर आप नहीं करते हैं:

  • पोस्टग्रेएसक्यूएल में मेरी टेबल पर उम्मीद से कम चुनें डिस्टिंक्ट है
  • प्रति उपयोगकर्ता नवीनतम पंक्ति पुनर्प्राप्त करने के लिए क्वेरी द्वारा समूह को अनुकूलित करें
  • समूहवार अधिकतम क्वेरी अनुकूलित करें
  • प्रति पंक्ति अंतिम N संबंधित पंक्तियों को क्वेरी करें

बेंचमार्क

अलग उत्तर देखें।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. psql में डेटाबेस कैसे स्विच करें?

  2. पोस्टग्रेज कॉलम X मौजूद नहीं है

  3. Postgresql में अंतर्राष्ट्रीयकृत नियमित अभिव्यक्ति

  4. PostgreSQL में एक तालिका को संदर्भित करने वाले संग्रहीत कार्यों की सूची बनाएं

  5. टेबल को पोस्टग्रेज करने के लिए डेटाफ्रेम कैसे लिखें?