PostgreSQL सूचकांक सरणी कॉलम कर सकते हैं?


144

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

मैंने एक int[]कॉलम के साथ एक साधारण तालिका बनाई , और उस पर एक अद्वितीय सूचकांक रखा। मैंने देखा कि मैं एक ही प्रकार की इन्ट्रीज नहीं जोड़ सका, जो मुझे विश्वास दिलाता है कि इंडेक्स एरे आइटम्स का सम्मिश्रण है, प्रत्येक आइटम का इंडेक्स नहीं।

INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');

SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");

क्या सूचकांक इस क्वेरी की मदद कर रहा है?


क्या डेटाटाइप jsonbका उपयोग करना और अनुक्रमित का उपयोग करना संभव है ? postgresql.org/docs/9.5/static/functions-json.html और postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXING
user3791372

जवाबों:


181

हां, आप किसी ऐरे को इंडेक्स कर सकते हैं, लेकिन आपको ऐरे ऑपरेटर्स और GIN-index टाइप का उपयोग करना होगा

उदाहरण:

    CREATE TABLE "Test"("Column1" int[]);
    INSERT INTO "Test" VALUES ('{10, 15, 20}');
    INSERT INTO "Test" VALUES ('{10, 20, 30}');

    CREATE INDEX idx_test on "Test" USING GIN ("Column1");

    -- To enforce index usage because we have only 2 records for this test... 
    SET enable_seqscan TO off;

    EXPLAIN ANALYZE
    SELECT * FROM "Test" WHERE "Column1" @> ARRAY[20];

परिणाम:

Bitmap Heap Scan on "Test"  (cost=4.26..8.27 rows=1 width=32) (actual time=0.014..0.015 rows=2 loops=1)
  Recheck Cond: ("Column1" @> '{20}'::integer[])
  ->  Bitmap Index Scan on idx_test  (cost=0.00..4.26 rows=1 width=0) (actual time=0.009..0.009 rows=2 loops=1)
        Index Cond: ("Column1" @> '{20}'::integer[])
Total runtime: 0.062 ms
ध्यान दें

ऐसा प्रतीत होता है कि कई मामलों में gin__int_ops विकल्प की आवश्यकता है

create index <index_name> on <table_name> using GIN (<column> gin__int_ops)

मैंने अभी तक ऐसा मामला नहीं देखा है जहां यह gin__int_ops विकल्पों के बिना && और @> ऑपरेटर के साथ काम करेगा


19
जैसा कि ओपी ने कहा है, यह वास्तव में व्यक्तिगत सरणी मानों को अनुक्रमित नहीं करता है, बल्कि पूरे सरणी को अनुक्रमित करता है। इसलिए, जबकि यह प्रश्न में क्वेरी की मदद करेगा (व्याख्या योजना देखें), इसका मतलब है कि आप व्यक्तिगत सरणी मानों पर अद्वितीय अवरोध (आसानी से) नहीं बना सकते हैं। उस ने कहा, यदि आप पूर्णांक सरणियों का उपयोग कर रहे हैं, तो आप व्यक्तिगत सरणी मानों को अनुक्रमित करने के लिए कंट्रिब मॉड्यूल "इंट्रैरे" का उपयोग कर सकते हैं, जो कई मामलों में बहुत तेज हो सकता है। (IIRC पाठ मानों के लिए इस पर कुछ काम किया जा रहा है, लेकिन योगदानकर्ताओं को संभवतः इसे समाप्त करने में मदद करने के लिए स्वागत किया जाएगा)।
xzilla 15

15
कृपया कोड उदाहरणों में PostgreSQL पहचानकर्ताओं में अपरकेस अक्षरों का उपयोग न करें, यह सिर्फ उन लोगों को भ्रमित करता है जो उद्धृत / केस तह नियमों से परिचित नहीं हैं, विशेष रूप से PostgreSQL के लिए नए लोग।
9

6
मेरी टिप्पणी को यहां दोहराने के लिए: मेरे अनुभव से, ये अनुक्रमणिकाएं बिना स्पीडअप के बहुत कम प्रदान करती हैं जब तक gin__int_ops कि integer[]कॉलम के लिए उपयोग नहीं किया जाता है । जब तक मैं इस सेशन क्लास को नहीं खोज लेता, तब तक मुझे हताशा और अन्य समाधानों की तलाश थी। यह एक सीमावर्ती चमत्कार कार्यकर्ता है।
IAMIC

1
@ आईआईसीआईसी का मतलब है कि मुझे स्ट्रिंग्स की एक सरणी को अनुक्रमित करने से परेशान नहीं होना चाहिए? और मुझे केवल पूर्णांक सरणियों को अनुक्रमित करना चाहिए?
ryan2johnson9

93

@Tregoreg ने अपनी पेशकश के लिए टिप्पणी में एक सवाल उठाया :

मुझे वर्तमान उत्तर काम नहीं मिला। सरणी-टाइप किए गए कॉलम पर GIN इंडेक्स का उपयोग करने से किसी भी () ऑपरेटर के प्रदर्शन में वृद्धि नहीं होती है। क्या वास्तव में कोई समाधान नहीं है?

@ फ्रैंक का स्वीकृत उत्तर आपको एरे ऑपरेटरों का उपयोग करने के लिए कहता है , जो अभी भी पोस्टग्रेज 11 के लिए सही है । मैनुअल:

... PostgreSQL के मानक वितरण में सरणियों के लिए GIN ऑपरेटर वर्ग शामिल है, जो इन ऑपरेटरों का उपयोग करके अनुक्रमित प्रश्नों का समर्थन करता है:

<@
@>
=
&&

मानक वितरण में GIN अनुक्रमित के लिए अंतर्निहित ऑपरेटर कक्षाओं की पूरी सूची यहां है।

पोस्टग्रैज इंडेक्स में ऑपरेटरों के लिए बाध्य होते हैं (जो कुछ प्रकारों के लिए लागू होते हैं), अकेले डेटा प्रकार या फ़ंक्शन या कुछ और नहीं। यह पोस्टग्रेज के मूल बर्कले डिजाइन से एक विरासत है और अब बदलना बहुत मुश्किल है। और यह आम तौर पर ठीक काम कर रहा है। यहाँ टॉम लेन की टिप्पणी के साथ pgsql- बग पर एक धागा है।

कुछ पोस्टगिस फ़ंक्शन (जैसे ST_DWithin()) इस प्रिंसिपल का उल्लंघन करते हैं, लेकिन ऐसा नहीं है। उन कार्यों को संबंधित ऑपरेटरों का उपयोग करने के लिए आंतरिक रूप से फिर से लिखा जाता है

अनुक्रमित अभिव्यक्ति ऑपरेटर के बाईं ओर होनी चाहिए । अधिकांश ऑपरेटरों ( उपरोक्त सभी सहित ) के लिए, क्वेरी प्लानर फ़्लिपिंग ऑपरेंड्स द्वारा इसे प्राप्त कर सकते हैं यदि आप अनुक्रमित अभिव्यक्ति को सही स्थान पर रखते हैं - जिसे COMMUTATORपरिभाषित किया गया है। ANYनिर्माण विभिन्न ऑपरेटरों के साथ संयोजन में उपयोग किया जा सकता है और एक ऑपरेटर ही नहीं है। जब सरणी तत्वों पर ऑपरेटर का constant = ANY (array_expression)समर्थन करने वाले केवल अनुक्रमित के रूप में उपयोग किया जाता है और हमें इसके लिए एक कम्यूटेटर की आवश्यकता होगी । GIN सूचकांक बाहर हैं।== ANY()

Postgres वर्तमान में GIN-indexable अभिव्यक्ति प्राप्त करने के लिए पर्याप्त स्मार्ट नहीं है। शुरुआत के लिए, constant = ANY (array_expression)है पूरी तरह से बराबर नहीं करने के लिए array_expression @> ARRAY[constant]। किसी भी NULL तत्वों के शामिल होने पर Array ऑपरेटर्स एक त्रुटि लौटाते हैं, जबकि ANYनिर्माण NULL से किसी भी तरफ निपट सकता है। और डेटा प्रकार के बेमेल के लिए अलग-अलग परिणाम हैं।

संबंधित उत्तर:

Asides

मूल्यों के बिना integerसरणियों ( int4, नहीं int2या नहीं int8) के साथ काम करते समय NULL(जैसे आपके उदाहरण का तात्पर्य है) अतिरिक्त मॉड्यूल पर विचार करें intarray, जो विशेष, तेज ऑपरेटरों और सूचकांक समर्थन प्रदान करता है। देख:

के रूप में UNIQUEके पर एक BTREE सूचकांक के साथ लागू किया है कि: अपने प्रश्न में बाधा है कि अनुत्तरित चला गया पूरे सरणी मूल्य (जैसे आप संदिग्ध) और के लिए खोज के साथ मदद नहीं करता है तत्वों सब पर। विवरण:


1
आआआआआआआआआआहह, अभी काफी शर्मिंदा महसूस कर रहा हूं, लेकिन यह मेरे दिमाग में नहीं आया कि पोस्टग्रैजिट्स इंडेक्स का उपयोग नहीं करेंगे भले ही सैद्धांतिक रूप से संभव हो। शायद यह इसलिए भी है कि मेरी कमी अंतर्दृष्टि में है, जैसे कि सूचकांक ऑपरेटरों के लिए बाध्य हैं। मेरे बीमार प्रश्न का उत्तर देने और अपने ज्ञान को साझा करने के लिए समय निकालने के लिए धन्यवाद!
ट्रेगोरग

6
@Tregoreg: बहुत शर्मिंदा मत हो, यह वास्तव में बहुत स्पष्ट नहीं है। मुझे याद है कि मैं खुद इससे उलझन में था जब मैं पहली बार इसमें गया था। जोड़ा गया सवाल और स्पष्टीकरण आम जनता के लिए काफी उपयोगी होना चाहिए।
इरविन ब्रान्डेसटेटर

1
मेरे अनुभव से, ये अनुक्रमणिकाएं बिना स्पीडअप के बहुत कम प्रदान करती हैं, जब तक gin__int_ops कि integer[]कॉलम के लिए उपयोग नहीं किया जाता है । जब तक मैं इस सेशन क्लास को नहीं खोज लेता, तब तक मुझे हताशा और अन्य समाधानों की तलाश थी। यह एक सीमावर्ती चमत्कार कार्यकर्ता है।
IAMIC

2
@ आईआईसीआईसी: मैंने घुसपैठ करने के लिए संकेत जोड़े। जैसा कि आपने बताया, उल्लेखनीय है।
एरविन ब्रान्डेसटेटर

के लिए ANY (array_expression) = constantभाव, जिन अनुक्रमित ठीक से काम?
user10375

37

अब व्यक्तिगत सरणी तत्वों को अनुक्रमित करना संभव है। उदाहरण के लिए:

CREATE TABLE test (foo int[]);
INSERT INTO test VALUES ('{1,2,3}');
INSERT INTO test VALUES ('{4,5,6}');
CREATE INDEX test_index on test ((foo[1]));
SET enable_seqscan TO off;

EXPLAIN ANALYZE SELECT * from test WHERE foo[1]=1;
                                                QUERY PLAN                                                    
------------------------------------------------------------------------------------------------------------------
 Index Scan using test_index on test  (cost=0.00..8.27 rows=1 width=32) (actual   time=0.070..0.071 rows=1 loops=1)
   Index Cond: (foo[1] = 1)
 Total runtime: 0.112 ms
(3 rows)

यह कम से कम Postgres 9.2.1 पर काम करता है। ध्यान दें कि आपको प्रत्येक सरणी इंडेक्स के लिए एक अलग इंडेक्स बनाने की आवश्यकता है, मेरे उदाहरण में मैंने केवल पहला तत्व इंडेक्स किया था।


28
इसे खो जाने न दें - यह दृष्टिकोण चर लंबाई सरणी के लिए निराशाजनक है जहां आप किसी भी () ऑपरेटर का उपयोग करना चाहते हैं।
14αrΚhικ

24
यह वास्तव में बहुत उपयोगी नहीं है। यदि आपके पास सरणी तत्वों की एक निश्चित संख्या है, तो आप प्रत्येक सरणी आइटम के लिए अधिक महंगी अभिव्यक्ति सूचकांक बनाने के बजाय प्रत्येक तत्व (और सादे बीटीआर सूचकांक) के लिए व्यक्तिगत कॉलम का उपयोग करेंगे। अलग-अलग स्तंभों का संग्रहण, बिना ओवरहेड के बहुत सस्ता है।
इरविन ब्रान्डेसटेटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.