PostgreSQL वास्तव में सरणी स्तंभों पर GIN अनुक्रमणिका का समर्थन करता है। दुर्भाग्य से, यह नहीं ARRAY[...] <@ indexed_col
के लिए प्रयोग करने योग्य प्रतीत नहीं होता है , और GIN
अनुक्रमणिका वैसे भी बार-बार अद्यतन की जाने वाली तालिकाओं के लिए अनुपयुक्त हैं।
डेमो:
- - यह परीक्षण करने के लिए कि क्या पीजी एक इंडेक्स का उपयोग कर सकता है, निम्नलिखित *केवल* का उपयोग करें-- उत्पादन में इसका उपयोग न करें। एसईटी सक्षम_सेकस्कैन =बंद @ arrtable.array_column);
दुर्भाग्य से, यह दर्शाता है कि लिखित रूप में हम अनुक्रमणिका का उपयोग नहीं कर सकते हैं। यदि आप उस शर्त को अस्वीकार नहीं करते हैं जिसका उपयोग किया जा सकता है, तो आप उन पंक्तियों को खोज और गिन सकते हैं जो करती हैं खोज तत्व शामिल करें (नहीं
को हटाकर) )
आप अनुक्रमणिका का उपयोग उन प्रविष्टियों को गिनने के लिए कर सकते हैं जो करती हैं लक्ष्य मान शामिल करें, फिर उस परिणाम को सभी प्रविष्टियों की गणना से घटाएं। चूंकि गिनती
PostgreSQL (9.1 और पुराने) में एक तालिका में सभी पंक्तियों को करना काफी धीमा है और इसके लिए क्रमिक स्कैन की आवश्यकता होती है, यह वास्तव में आपकी वर्तमान क्वेरी की तुलना में धीमा होगा। यदि आपके पास id
पर एक b-tree अनुक्रमणिका है, तो यह संभव है कि 9.2 पर केवल-इंडेक्स स्कैन का उपयोग पंक्तियों को गिनने के लिए किया जा सकता है , इस मामले में यह वास्तव में ठीक हो सकता है:
चुनें (सेलेक्ट काउंट (आईडी) एरटेबल से) - (सेलेक्ट काउंट (आईडी) एररटेबल से जहां (ARRAY[1] <@ arrtable.array_column));
Pg 9.1 और उससे नीचे के लिए आपके मूल संस्करण से खराब प्रदर्शन की गारंटी है, क्योंकि seqscan के अलावा आपके मूल संस्करण को भी की आवश्यकता होती है GIN इंडेक्स स्कैन की जरूरत है। मैंने अब 9.2 पर इसका परीक्षण किया है और ऐसा लगता है कि यह गिनती के लिए एक इंडेक्स का उपयोग करता है, इसलिए यह 9.2 की खोज के लायक है। कुछ कम तुच्छ डमी डेटा के साथ:
ड्रॉप इंडेक्स arrtable_arraycolumn_gin_arr_idx;truncate टेबल arrtable;arrtable में डालें (id, array_column) सेलेक्ट s, ARRAY[1,2,s,s*2,s*3,s/2,s/4] FROM Generate_series(1,1000000) s;CREATE INDEX arrtable_arraycolumn_gin_arr_idxON गिरफ्तारी योग्य GIN(array_column);
ध्यान दें कि इस तरह का एक GIN इंडेक्स अपडेट को बहुत धीमा कर देगा, और पहली जगह में बनाने में काफी धीमा है। यह उन तालिकाओं के लिए उपयुक्त नहीं है जो बिल्कुल भी अपडेट हो जाती हैं - जैसे आपकी तालिका।
इससे भी बदतर, इस अनुक्रमणिका का उपयोग करने वाली क्वेरी आपकी मूल क्वेरी से दुगुनी और अधिकतम आधी लंबी होती है एक ही डेटा सेट पर। यह उन मामलों के लिए सबसे खराब है जहां सूचकांक बहुत चयनात्मक नहीं है जैसे ARRAY[1]
- मूल क्वेरी के लिए 4s बनाम 2s। जहां अनुक्रमणिका अत्यधिक चयनात्मक होती है (अर्थात:ARRAY[199]
. जैसे कई मिलान नहीं होते हैं ) यह मूल के 3s बनाम लगभग 1.2 सेकंड में चलता है। यह अनुक्रमणिका इस क्वेरी के लिए उपयुक्त नहीं है।
यहाँ सबक? कभी-कभी, अनुक्रमिक स्कैन करना ही सही उत्तर होता है।
चूंकि यह आपकी हिट दरों के लिए काम नहीं करेगा, या तो एक ट्रिगर के साथ एक भौतिक दृश्य बनाए रखें जैसा कि @debenhur सुझाव देता है, या सरणी को उन मापदंडों की सूची के रूप में उलटने का प्रयास करें जो प्रविष्टि नहीं करती है जैसा कि @maniek सुझाव देते हैं, आप एक GiST अनुक्रमणिका का उपयोग कर सकते हैं।