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

पोस्टग्रेएसक्यूएल बी-ट्री इंडेक्स पर नोट्स

PostgreSQL कम से कम 6 विभिन्न प्रकार के इंडेक्स के साथ आता है, जिसमें B-Treeindex सबसे अधिक इस्तेमाल किया जाता है। PostgreSQL में B-Treeindexes के बारे में और जानने के लिए पढ़ें।

इंडेक्स के प्रकार

PostgreSQL में एक इंडेक्स, जैसे कि एक क्रिएट टेबल स्टेटमेंट में प्राथमिक कुंजी और अद्वितीय के लिए बनाया गया है या एक क्रिएट इंडेक्स स्टेटमेंट के साथ स्पष्ट रूप से बनाया गया है, एक विशेष "प्रकार" के हैं (हालांकि तकनीकी रूप से हमें उन्हें "इंडेक्सएक्सेस विधियों" कहना चाहिए)।

PostgreSQL इन बिल्ट-इन इंडेक्स प्रकारों के साथ आता है:

  • बी-ट्री
  • हैश
  • GIN - सामान्यीकृत उलटा सूचकांक
  • BRIN - ब्लॉक रेंज इंडेक्स (केवल v9.5 और इसके बाद के संस्करण में)
  • GiST - सामान्यीकृत उलटा खोज वृक्ष
  • SP-GiST - स्पेस पार्टिशनेड GiST

बी-ट्री डिफ़ॉल्ट और सबसे अधिक इस्तेमाल किया जाने वाला इंडेक्स प्रकार है। क्रिएट टेबल स्टेटमेंट के भीतर प्राथमिक कुंजी या एक अद्वितीय निर्दिष्ट करने से पोस्टग्रेएसक्यूएल बी-ट्री इंडेक्स बनाता है। बिना यूजिंग क्लॉज के क्रिएट इंडेक्स स्टेटमेंट्स भी बी-ट्री इंडेक्स बनाएंगे:

-- the default index type is btree
CREATE INDEX ix_year ON movies (year);

-- equivalent, explicitly lists the index type
CREATE INDEX ix_year ON movies USING btree (year);

आदेश देना

बी-ट्री इंडेक्स स्वाभाविक रूप से ऑर्डर किए जाते हैं। इंडेक्स किए गए एक्सप्रेशन को सॉर्ट करने के बजाय PostgreSQL इस ऑर्डर का उपयोग कर सकता है। उदाहरण के लिए, सभी 80 के दशक की फिल्मों के शीर्षक को शीर्षक के आधार पर क्रमबद्ध करने के लिए एक प्रकार की आवश्यकता होगी:

idxdemo=# explain select title from movies where year between 1980 and 1989 order by title asc;
                                    QUERY PLAN
----------------------------------------------------------------------------------
 Sort  (cost=240.79..245.93 rows=2056 width=17)
   Sort Key: title
   ->  Index Scan using ix_year on movies  (cost=0.29..127.65 rows=2056 width=17)
         Index Cond: ((year >= 1980) AND (year <= 1989))
(4 rows)

लेकिन अगर आप उन्हें अनुक्रमित कॉलम (वर्ष) के अनुसार क्रमबद्ध कर रहे हैं, तो अतिरिक्त क्रम की आवश्यकता नहीं है।

idxdemo=# explain select title from movies where year between 1980 and 1989 order by year asc;
                                 QUERY PLAN
----------------------------------------------------------------------------
 Index Scan using ix_year on movies  (cost=0.29..127.65 rows=2056 width=21)
   Index Cond: ((year >= 1980) AND (year <= 1989))
(2 rows)

फ़ैक्टर भरें

उन तालिकाओं के लिए जो अपडेट नहीं होने जा रही हैं, आप "भरने के कारक" को 90 के डिफ़ॉल्ट से बढ़ा सकते हैं, जो आपको थोड़ा छोटा और तेज़ इंडेक्स देना चाहिए। इसके विपरीत, यदि अनुक्रमित पैरामीटर को शामिल करने वाली तालिका के बार-बार अद्यतन होते हैं, तो आप भरण कारक को एक छोटी संख्या तक कम कर सकते हैं - यह थोड़े बड़े अनुक्रमितों की कीमत पर तेजी से सम्मिलित और अद्यतन करने की अनुमति देगा।

CREATE INDEX ix_smd ON silent_movies (director) WITH (fillfactor = 100);

टेक्स्ट पर इंडेक्स करना

बी-ट्री इंडेक्स टेक्स्ट के प्रीफिक्स मैचिंग में मदद कर सकते हैं। आइए 'T' अक्षर से शुरू होने वाली सभी फिल्मों को सूचीबद्ध करने के लिए एक प्रश्न पूछें:

idxdemo=> explain select title from movies where title like 'T%';
                         QUERY PLAN
-------------------------------------------------------------
 Seq Scan on movies  (cost=0.00..1106.94 rows=8405 width=17)
   Filter: (title ~~ 'T%'::text)
(2 rows)

यह योजना तालिका के पूर्ण अनुक्रमिक स्कैन की मांग करती है। क्या होता है अगर हम मूवी.शीर्षक पर बी-ट्री इंडेक्स जोड़ते हैं?

idxdemo=> create index ix_title on movies (title);
CREATE INDEX

idxdemo=> explain select title from movies where title like 'T%';
                         QUERY PLAN
-------------------------------------------------------------
 Seq Scan on movies  (cost=0.00..1106.94 rows=8405 width=17)
   Filter: (title ~~ 'T%'::text)
(2 rows)

खैर, इससे बिल्कुल भी मदद नहीं मिली। हालांकि, मैजिक पिक्सी डस्ट का एक रूप है जिसे हम पोस्टग्रेज को वह करने के लिए छिड़क सकते हैं जो हम चाहते हैं:

idxdemo=> create index ix_title2 on movies (title text_pattern_ops);
CREATE INDEX

idxdemo=> explain select title from movies where title like 'T%';
                                 QUERY PLAN
-----------------------------------------------------------------------------
 Bitmap Heap Scan on movies  (cost=236.08..1085.19 rows=8405 width=17)
   Filter: (title ~~ 'T%'::text)
   ->  Bitmap Index Scan on ix_title2  (cost=0.00..233.98 rows=8169 width=0)
         Index Cond: ((title ~>=~ 'T'::text) AND (title ~<~ 'U'::text))
(4 rows)

योजना अब एक सूचकांक का उपयोग करती है, और लागत कम हो गई है। यहां जादू "text_pattern_ops" है जो बी-ट्री इंडेक्स को "टेक्स्ट" अभिव्यक्ति पर पैटर्न ऑपरेटरों (जैसे और नियमित अभिव्यक्ति) के लिए उपयोग करने की अनुमति देता है। “text_pattern_ops” को ऑपरेटर क्लास कहा जाता है।

ध्यान दें कि यह केवल एक निश्चित टेक्स्ट प्रीफ़िक्स वाले पैटर्न के लिए काम करेगा, इसलिए "% एंग्री%" या "% मेन" काम नहीं करेगा। उन्नत टेक्स्ट क्वेरी के लिए PostgreSQL की पूर्ण टेक्स्ट खोज का उपयोग करें।

कवरिंग इंडेक्स

कवरिंग इंडेक्स को v11 में PostgreSQL में जोड़ा गया था। कवरिंग इंडेक्स आपको इंडेक्स के अंदर इंडेक्स किए गए एक्सप्रेशन के साथ एक या एक से अधिक एक्सप्रेशन का मान शामिल करने देता है।

आइए रिलीज़ के वर्ष के अनुसार सभी फ़िल्मों के शीर्षकों के लिए क्वेरी करने का प्रयास करें:

idxdemo=# explain select title from movies order by year asc;
                             QUERY PLAN
--------------------------------------------------------------------
 Sort  (cost=3167.73..3239.72 rows=28795 width=21)
   Sort Key: year
   ->  Seq Scan on movies  (cost=0.00..1034.95 rows=28795 width=21)
(3 rows)

इसमें तालिका का एक पूर्ण अनुक्रमिक स्कैन शामिल है, इसके बाद एक प्रकार के अनुमानित कॉलम शामिल हैं। आइए सबसे पहले movies.year पर एक नियमित अनुक्रमणिका जोड़ें:

idxdemo=# create index ix_year on movies (year);
CREATE INDEX

idxdemo=# explain select title from movies order by year asc;
                                  QUERY PLAN
------------------------------------------------------------------------------
 Index Scan using ix_year on movies  (cost=0.29..1510.22 rows=28795 width=21)
(1 row)

अब Postgres वांछित क्रम में सीधे तालिका से प्रविष्टियों को बाहर निकालने के लिए अनुक्रमणिका का उपयोग करने का निर्णय लेता है। तालिका को देखने की आवश्यकता है क्योंकि सूचकांक में केवल 'वर्ष' का मान और तालिका में टपल का संदर्भ होता है।

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

idxdemo=# create index ix_year_cov on movies (year) include (title);
CREATE INDEX
Time: 92.618 ms

idxdemo=# drop index ix_year;
DROP INDEX

idxdemo=# explain select title from movies order by year asc;
                                      QUERY PLAN
---------------------------------------------------------------------------------------
 Index Only Scan using ix_year_cov on movies  (cost=0.29..2751.59 rows=28795 width=21)
(1 row)

पोस्टग्रेज अब इंडेक्स ओनलीस्कैन का उपयोग कर रहा है, जिसका अर्थ है कि टेबल लुकअप पूरी तरह से बचा हुआ है। ध्यान दें कि हमें पुरानी अनुक्रमणिका को छोड़ना पड़ा, क्योंकि पोस्टग्रेज़ ने इस क्वेरी के लिए ix_year से अधिक ix_year_cov को नहीं चुना।

क्लस्टरिंग

अन्य RDBMS में "क्लस्टर इंडेक्स" के विपरीत, PostgreSQL कुख्यात रूप से एक तालिका में पंक्तियों के स्वचालित भौतिक क्रम का समर्थन नहीं करता है। यदि आपके अधिकांश प्रश्न एक निश्चित क्रम में अधिकतर स्थिर तालिका की अधिकांश पंक्तियों को खींचने जा रहे हैं, तो उस क्रम में भौतिक तालिका संग्रहण को लेआउट करना और अनुक्रमिक स्कैन का उपयोग करना एक अच्छा विचार होगा। किसी अनुक्रमणिका द्वारा निर्धारित क्रम में किसी तालिका को भौतिक रूप से पुन:व्यवस्थित करने के लिए, उपयोग करें:

CLUSTER VERBOSE movies USING ix_year;

आप आमतौर पर किसी तालिका को फिर से संगठित करने के लिए B-Tree अनुक्रमणिका का उपयोग करते हैं, क्योंकि यह तालिका में सभी पंक्तियों के लिए एक पूर्ण क्रम प्रदान करती है।

सूचकांक आँकड़े

आपकी अनुक्रमणिका कितनी डिस्क स्थान लेती है? pg_relation_sizefunction इसका उत्तर दे सकता है:

idxdemo=# select * from pg_relation_size('ix_year');
 pg_relation_size
------------------
           663552
(1 row)

यह अनुक्रमणिका द्वारा उपयोग किए गए डिस्क स्थान को बाइट्स में लौटाता है।

मानक एक्सटेंशनpgstattuple का उपयोग करके सूचकांक के बारे में अधिक जानकारी एकत्र की जा सकती है। इससे पहले कि आप नीचे दिए गए कार्यों का उपयोग करें, आपको एक CREATE EXTENSION pgstattuple; करने की आवश्यकता है एक सुपरयुसर के रूप में प्रासंगिक डेटाबेस में। इन कार्यों के उपयोग के लिए भी सुपरयूज़र विशेषाधिकारों की आवश्यकता होती है।

pgstattuple फ़ंक्शन अन्य बातों के अलावा, अप्रयुक्त (free_space .) लौटाता है )और पुन:प्रयोज्य (dead_tuple_len ) सूचकांक के भीतर डिस्क स्थान। यह तय करने में बहुत मददगार हो सकता है कि REINDEX run चलाना है या नहीं इंडेक्स ब्लोट को कम करने के लिए।

idxdemo=# select * from pgstattuple('ix_year'::regclass);
-[ RECORD 1 ]------+-------
table_len          | 663552
tuple_count        | 28795
tuple_len          | 460720
tuple_percent      | 69.43
dead_tuple_count   | 0
dead_tuple_len     | 0
dead_tuple_percent | 0
free_space         | 66232
free_percent       | 9.98

pgstattuple फ़ंक्शन बी-ट्री विशिष्ट जानकारी देता है, जिसमें पेड़ का स्तर भी शामिल है:

idxdemo=# select * from pgstatindex('ix_year'::regclass);
-[ RECORD 1 ]------+-------
version            | 2
tree_level         | 1
index_size         | 663552
root_block_no      | 3
internal_pages     | 1
leaf_pages         | 79
empty_pages        | 0
deleted_pages      | 0
avg_leaf_density   | 89.72
leaf_fragmentation | 0

इसका उपयोग यह तय करने के लिए किया जा सकता है कि सूचकांक के भरण कारक को समायोजित करना है या नहीं।

बी-ट्री इंडेक्स सामग्री की जांच करना

यहां तक ​​कि बी-ट्री की सामग्री की भी सीधे जांच की जा सकती है, इसके लिए एक्सटेंशन पेज का निरीक्षण किया जा सकता है। इस एक्सटेंशन के उपयोग के लिए सुपरयूज़र विशेषाधिकारों की आवश्यकता होती है।

इंडेक्स के एक पेज (यहां, 13वां पेज) के गुण यहां दिए गए हैं:

idxdemo=# select * from bt_page_stats('ix_year', 13);
-[ RECORD 1 ]-+-----
blkno         | 13
type          | l
live_items    | 367
dead_items    | 0
avg_item_size | 16
page_size     | 8192
free_size     | 808
btpo_prev     | 12
btpo_next     | 14
btpo          | 0
btpo_flags    | 1

और यहां पृष्ठ में प्रत्येक आइटम की वास्तविक सामग्री (यहां 5 तक सीमित) हैं:

idxdemo=# select * from bt_page_items('ix_year', 13) limit 5;
 itemoffset |   ctid   | itemlen | nulls | vars |          data
------------+----------+---------+-------+------+-------------------------
          1 | (104,40) |      16 | f     | f    | 86 07 00 00 00 00 00 00
          2 | (95,38)  |      16 | f     | f    | 86 07 00 00 00 00 00 00
          3 | (95,39)  |      16 | f     | f    | 86 07 00 00 00 00 00 00
          4 | (95,40)  |      16 | f     | f    | 86 07 00 00 00 00 00 00
          5 | (96,1)   |      16 | f     | f    | 86 07 00 00 00 00 00 00
(5 rows)

और यदि आप प्रत्येक पृष्ठ पर कुछ एकत्र करने के लिए एक प्रश्न लिखने की सोच रहे हैं, तो आपको संबंध में पृष्ठों की कुल संख्या की भी आवश्यकता होगी, जो pg_relpages के माध्यम से उत्पन्न हो सकते हैं pgstattuple . से विस्तार:

idxdemo=# select pg_relpages('ix_year');
 pg_relpages
-------------
          81
(1 row)

अन्य इंडेक्स प्रकार

प्रश्नों को अनुकूलित करने के लिए बी-ट्री इंडेक्स बहुमुखी उपकरण हैं। थोड़े से प्रयोग और योजना के साथ, इसका उपयोग अनुप्रयोगों के प्रतिक्रिया समय को बेहतर बनाने और नौकरियों की रिपोर्ट करने के लिए किया जा सकता है।

PostgreSQL के अन्य इंडेक्स प्रकार भी उपयोगी हैं और विशिष्ट मामलों में बी-ट्री की तुलना में अधिक कुशल और प्रदर्शनकारी हो सकते हैं। यह लेख सभी प्रकार की संक्षिप्त जानकारी देता है।

अनुक्रमणिका के बारे में कोई टिप मिली जिसे आप साझा करना चाहते हैं? उन्हें नीचे एक टिप्पणी के रूप में छोड़ दें!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. लिनक्स पर पायथन पैकेज कैसे स्थापित करें ताकि यह पहले से काम कर रहे PostgreSQL 13 plpython3u एक्सटेंशन द्वारा मिल जाए?

  2. PostgreSQL में XML फ़ाइलें आयात करें

  3. पॉइंट इन टाइम रिकवरी का उपयोग करके अपने पोस्टग्रेएसक्यूएल डेटाबेस के लिए आरपीओ को कम कैसे करें

  4. Django JSONField फ़िल्टरिंग

  5. PostgreSQL डेटाबेस को कहाँ स्टोर करता है?