सही परिणाम?
सबसे पहले: शुद्धता। आप अद्वितीय तत्वों की एक सरणी का उत्पादन करना चाहते हैं? आपकी वर्तमान क्वेरी ऐसा नहीं करती है। इन्ट्रेयर मॉड्यूलuniq()
से फ़ंक्शन केवल वादे करता है:
आसन्न डुप्लिकेट निकालें
मैनुअल में दिए गए निर्देशों की तरह , आपको इसकी आवश्यकता होगी:
SELECT l.d + r.d, uniq(sort(array_agg_mult(r.arr)))
FROM ...
साथ ही आपको हल किए गए ऐरे देता है - यह मानते हुए कि आप चाहते हैं, आपने स्पष्ट नहीं किया।
मुझे लगता है कि आपके पास sort()
आपकी फिडेल है , इसलिए यह आपके प्रश्न में एक टाइपो हो सकता है।
पोस्टगर्ल्स 9.5
किसी भी तरह से, आप नए Postgres 9.5 (वर्तमान में बीटा) से प्यार करेंगे । यह array_agg_mult()
बॉक्स से बाहर की क्षमता प्रदान करता है और बहुत तेजी से:
सरणी हैंडलिंग के लिए अन्य प्रदर्शन सुधार भी हुए हैं।
सवाल
इसका मुख्य उद्देश्य array_agg_mult()
बहु-आयामी सरणियों को एकत्रित करना है, लेकिन आप केवल 1-आयामी सरणियों का उत्पादन करते हैं। इसलिए मैं कम से कम इस वैकल्पिक प्रश्न की कोशिश करूंगा:
SELECT l.d + r.d AS d_sum, array_agg(DISTINCT elem) AS result_arr
FROM left2 l
JOIN right2 r USING (t1)
, unnest(r.arr) elem
GROUP BY 1
ORDER BY 1;
जो आपके प्रश्न को भी संबोधित करता है:
क्या कुल फ़ंक्शन सीधे डुप्लिकेट को हटा सकता है?
हाँ, यह कर सकते हैं, के साथ DISTINCT
। लेकिन यह uniq()
पूर्णांक सरणियों से अधिक तेज़ नहीं है , जिसे पूर्णांक सरणियों के लिए अनुकूलित किया गया है, जबकि DISTINCT
सभी योग्य डेटा प्रकारों के लिए सामान्य है।
intarray
मॉड्यूल की आवश्यकता नहीं है हालांकि , परिणाम आवश्यक रूप से सॉर्ट नहीं किया गया है। Postgres DISTINCT
(IIRC) के लिए अलग-अलग एल्गोरिदम का उपयोग करता है , बड़े सेट आमतौर पर हैशेड होते हैं, फिर परिणाम तब तक सॉर्ट नहीं किया जाता है जब तक आप स्पष्ट नहीं जोड़ते हैं ORDER BY
। यदि आपको हल किए गए सरणियों की आवश्यकता है, तो आप सीधे कुल कार्य में जोड़ सकते हैं ORDER BY
:
array_agg(DISTINCT elem ORDER BY elem)
लेकिन यह आमतौर पर पूर्व-सॉर्ट किए गए डेटा (एक बड़े सॉर्ट बनाम कई छोटे प्रकार) को खिलाने की तुलना में धीमा है array_agg()
। इसलिए मैं एक उप-क्षेत्र में और फिर समग्र करना चाहूंगा :
SELECT d_sum, uniq(array_agg(elem)) AS result_arr
FROM (
SELECT l.d + r.d AS d_sum, elem
FROM left2 l
JOIN right2 r USING (t1)
, unnest(r.arr) elem
ORDER BY 1, 2
) sub
GROUP BY 1
ORDER BY 1;
Postgres 9.4 पर मेरे सरसरी परीक्षण में यह सबसे तेज़ संस्करण था।
एसक्यूएल फिडल आपके द्वारा प्रदत्त एक के आधार पर।
सूची
मुझे यहां किसी भी सूचकांक के लिए ज्यादा संभावनाएं नहीं दिख रही हैं। एकमात्र विकल्प होगा:
CREATE INDEX ON right2 (t1, arr);
केवल तभी समझ में आता है जब आपको इसमें से केवल-इंडेक्स स्कैन मिलते हैं - जो तब होगा जब अंतर्निहित तालिका right2
केवल इन दो स्तंभों की तुलना में व्यापक रूप से व्यापक हो और आपका सेटअप केवल-केवल स्कैन के लिए योग्य हो । पोस्टग्रैज विकी में विवरण।
right2.arr
आपके डेमो स्कीमा की तरह NULL हो सकता है? क्या आपको परिणाम के रूप में क्रमबद्ध सरणियों की आवश्यकता है?