किसी तालिका से सभी या अधिकतर पंक्तियों को पुनर्प्राप्त करते समय, इस प्रकार की क्वेरी के लिए सबसे तेज़ तरीका आमतौर पर पहले को समेकित/असंबद्ध करना है और शामिल हों बाद में :
SELECT *
FROM products p
JOIN (
SELECT DISTINCT ON (product_id) *
FROM meta
ORDER BY product_id, id DESC
) m ON m.product_id = p.id;
meta
. में जितनी अधिक पंक्तियां products
. में प्रति पंक्ति , प्रदर्शन पर जितना बड़ा प्रभाव होगा।
बेशक, आप एक ORDER BY
जोड़ना चाहेंगे सबक्वेरी में क्लॉज जो . को परिभाषित करता है सबक्वायरी में प्रत्येक सेट फॉर्म लेने के लिए पंक्ति। @ क्रेग और @ क्लोडोआल्डो ने आपको इसके बारे में पहले ही बता दिया था। मैं meta
लौटा रहा हूं उच्चतम id
. के साथ पंक्ति ।
एसक्यूएल फिडल।
DISTINCT ON
. के लिए विवरण :
- समूह द्वारा प्रत्येक समूह में पहली पंक्ति का चयन करें?
प्रदर्शन अनुकूलित करें
फिर भी, यह हमेशा सबसे तेज़ समाधान नहीं होता है। डेटा वितरण के आधार पर कई अन्य क्वेरी शैलियाँ हैं। इस साधारण मामले के लिए एक और जुड़ाव शामिल है, यह बड़ी तालिकाओं के साथ एक परीक्षण में काफी तेजी से चला:
SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM (
SELECT product_id, max(id) AS meta_id
FROM meta
GROUP BY 1
) sub
JOIN meta m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;
यदि आप गैर-वर्णनात्मक id
का उपयोग नहीं करेंगे कॉलम नामों के रूप में, हम टकरावों के नामकरण में नहीं चलेंगे और केवल SELECT p.*, m.*
लिख सकते हैं। . (मैं कभी नहीं id
का उपयोग करें कॉलम नाम के रूप में।)
यदि प्रदर्शन आपकी सर्वोपरि आवश्यकता है, तो अधिक विकल्पों पर विचार करें:
- एक
MATERIALIZED VIEW
meta
. से पूर्व-एकत्रित डेटा के साथ , अगर आपका डेटा नहीं बदलता है (ज्यादा)। - एक पुनरावर्ती सीटीई जो एक ढीले सूचकांक स्कैन का अनुकरण करता है एक बड़े . के लिए
meta
अनेक . के साथ तालिका प्रति उत्पाद पंक्तियाँ (अपेक्षाकृत कुछ अलगproduct_id
)।
यह एकमात्र तरीका है जिससे मैं पूरी तालिका में एक DISTINCT क्वेरी के लिए एक इंडेक्स का उपयोग करना जानता हूं।