बिटमैप इंडेक्स स्कैन के साथ क्वेरी प्लान में "रीचेक कोंड:" लाइन


21

यह पिछले प्रश्न के लिए टिप्पणियों से एक स्पिन-ऑफ है:

PostgreSQL 9.4 का उपयोग करते हुए, Recheck Cond:क्वेरी प्लान आउटपुट में बिटमैप इंडेक्स स्कैन के बाद हमेशा एक लाइन लगती है EXPLAIN

EXPLAINसंदर्भित प्रश्न के आउटपुट में जैसे:

->  Bitmap Heap Scan on table_three  (cost=2446.92..19686.74 rows=8159 width=7)
      Recheck Cond: (("timestamp" > (now() - '30 days'::interval)) AND (client_id > 0))
      ->  BitmapAnd  (cost=2446.92..2446.92 rows=8159 width=0)
            ->  Bitmap Index Scan on table_one_timestamp_idx  (cost=0.00..1040.00 rows=79941 width=0)
                  Index Cond: ("timestamp" > (now() - '30 days'::interval))
            ->  Bitmap Index Scan on fki_table_three_client_id  (cost=0.00..1406.05 rows=107978 width=0)
                  Index Cond: (client_id > 0)

या EXPLAIN ANALYZEएक सरल, विशाल तालिका के लिए आउटपुट में (बहुत कम के साथ work_mem):

EXPLAIN ANALYZE SELECT * FROM aa WHERE a BETWEEN 100000 AND 200000;
Bitmap Heap Scan on aa  (cost=107.68..4818.05 rows=5000 width=4) (actual time=27.629..213.606 rows=100001 loops=1)
  Recheck Cond: ((a >= 100000) AND (a <= 200000))
  Rows Removed by Index Recheck: 758222
  Heap Blocks: exact=693 lossy=3732
  ->  Bitmap Index Scan on aai  (cost=0.00..106.43 rows=5000 width=0) (actual time=27.265..27.265 rows=100001 loops=1)
        Index Cond: ((a >= 100000) AND (a <= 200000))

क्या इसका मतलब है कि बिटकॉइन इंडेक्स स्कैन के बाद दूसरी बार इंडेक्स स्थितियों की जांच की जानी चाहिए?
हम EXPLAINआउटपुट से और क्या सीख सकते हैं ?

जवाबों:


17

जैसा कि @ क्रिस ने संदर्भित प्रश्न पर सही टिप्पणी की :

एक छोटी सी जांच से यह संकेत मिलता है कि रीचेक की स्थिति हमेशा में मुद्रित होती है EXPLAIN, लेकिन वास्तव में केवल तब ही प्रदर्शन किया जाता है जब work_memछोटा सा नुकसान हो सकता है। विचार? http://www.postgresql.org/message-id/464F3C5D.2000700@enterprisedb.com

हालांकि यह सब सच है और मुख्य विकासकर्ता हिक्की लिनकांगास प्रथम श्रेणी का स्रोत है, यह पोस्ट 2007 की है (पोस्टग्रैस 8.2)। यहां माइकल पैक्विर द्वारा पोस्टग्रेज 9.4 के लिए विस्तृत विवरण के साथ एक ब्लॉग पोस्ट है , जहां EXPLAIN ANALYZEअधिक जानकारी के साथ आउटपुट में सुधार किया गया है।

Recheck Cond:लाइन है हमेशा वहाँ बिटमैप सूचकांक स्कैन के लिए। बेसिक का आउटपुट EXPLAINहमें अधिक नहीं बताएगा। हमें अतिरिक्त जानकारी मिलती है EXPLAIN ANALYZEजैसा कि प्रश्न में दूसरी बोली में देखा जा सकता है:

Heap Blocks: exact=693 lossy=3732

कुल 4425 डेटा पेज (ब्लॉक) से, 693 ने ट्यूपल को बिल्कुल (टपल पॉइंटर्स सहित ) संग्रहीत किया , जबकि अन्य 3732 पेज बिटमैप में हानिपूर्ण (सिर्फ डेटा पेज) थे। यह तब होता है जब work_memसूचकांक स्कैन से निर्मित पूरे बिटमैप को स्टोर करने के लिए पर्याप्त बड़ा नहीं होता है (दोषरहित)।

सूचकांक की स्थिति को हानिपूर्ण हिस्से से पृष्ठों के लिए फिर से जांचना पड़ता है, क्योंकि बिटमैप केवल यह याद रखता है कि कौन से पेज लाने हैं और पेज पर सटीक ट्यूपल्स नहीं हैं। पृष्ठ पर सभी tuples आवश्यक रूप से अनुक्रमणिका शर्तों को पारित नहीं करेंगे, यह आवश्यक है कि वास्तव में स्थिति की पुनरावृत्ति हो।

यह pgsql हैकर्स पर धागा है जहां नए जोड़ पर चर्चा की गई थी । लेखक Etsuro Fujitawork_mem हानिपूर्ण बिटमैप प्रविष्टियों और आगामी स्थिति की जाँच से बचने के लिए न्यूनतम गणना करने के लिए एक सूत्र प्रदान करता है । गणना कई बिटमैप स्कैन के साथ जटिल मामलों के लिए विश्वसनीय नहीं है, इसलिए इसका उपयोग वास्तविक संख्याओं से आउटपुट के लिए नहीं किया गया था EXPLAIN। यह अभी भी सरल मामलों के लिए एक अनुमान के रूप में काम कर सकता है।

अतिरिक्त लाइन BUFFERS:

इसके अलावा, जब BUFFERSविकल्प के साथ चल रहा हो : EXPLAIN (ANALYZE, BUFFERS) ...एक और लाइन जोड़ी जाती है जैसे:

Buffers: shared hit=279 read=79

यह इंगित करता है कि कैश ( shared hit=279) से कितना अंतर्निहित तालिका (और सूचकांक) पढ़ा गया था और डिस्क ( read=79) से कितना प्राप्त किया जाना था । यदि आप क्वेरी को दोहराते हैं, तो "पढ़ा गया" भाग आम तौर पर बहुत अधिक प्रश्नों के लिए गायब हो जाता है, क्योंकि पहले कॉल के बाद अब सब कुछ कैश हो गया है। पहला कॉल आपको बताता है कि पहले से ही कितना कैश किया गया था। बाद की कॉल यह बताती है कि आपका कैश कितना (वर्तमान में) संभाल सकता है।

और भी विकल्प हैं। विकल्प के बारे में मैनुअल BUFFERS:

विशेष रूप से, साझा किए गए ब्लॉक हिट की संख्या, पढ़ें, गंदे, और लिखे गए, स्थानीय ब्लॉक की संख्या हिट, रीड, डस्टीएड और लिखित हैं, और पढ़े और लिखे हुए टेम्प ब्लॉक की संख्या।

आगे पढ़ें, और भी बहुत कुछ स्रोत कोड
में आउटपुट विकल्पों की सूची यहां दी गई है ।


10

इरविन, चूंकि यह हमारी टिप्पणी से पहले चर्चा में था, मैंने इसे थोड़ा और आगे बढ़ाने का फैसला किया ...

मेरे पास यथोचित आकार की तालिका से एक बहुत ही सरल क्वेरी है। मेरे पास आमतौर पर पर्याप्त है work_mem, लेकिन इस मामले में मैंने आदेशों का उपयोग किया है

SET work_mem = 64;

बहुत छोटा work_memऔर सेट करने के लिए

SET work_mem = default;

work_memमेरी क्वेरी के लिए पर्याप्त रूप से बड़े होने के लिए मेरी पीठ सेट करने के लिए।

एक्सप्लेन और रीचेक कंडीशन

इसलिए, केवल के EXPLAINरूप में मेरी क्वेरी चल रही है

EXPLAIN 
SELECT * FROM olap.reading_facts
WHERE meter < 20;

मैंने निम्न और उच्च दोनों के लिए परिणाम प्राप्त किए work_mem:

कम work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

उच्च work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

लंबी कहानी छोटी है, EXPLAINकेवल के लिए, जैसा कि उम्मीद थी कि क्वेरी योजना इंगित करती है कि एक रीचेक स्थिति संभव है, लेकिन हम यह नहीं जान सकते कि क्या वास्तव में गणना की जाएगी।

विश्लेषण और स्थिति को फिर से जाँचें

जब हम ANALYZEक्वेरी में शामिल होते हैं , तो परिणाम हमें उस बारे में अधिक बताते हैं जो हमें जानना आवश्यक है।

कम work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Rows Removed by Index Recheck: 86727
  Heap Blocks: exact=598 lossy=836
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
        Index Cond: (meter < 20)

उच्च work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Heap Blocks: exact=1434
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
        Index Cond: (meter < 20)

फिर से, जैसा कि अपेक्षित था, ANALYZEहमें कुछ बहुत महत्वपूर्ण जानकारी का पता चलता है। निम्न work_memस्थिति में, हम देखते हैं कि अनुक्रमणिका जाँच द्वारा निकाली गई पंक्तियाँ हैं, और हमारे पास lossyढेर ब्लॉक हैं।

निष्कर्ष? (या उसके अभाव)

दुर्भाग्य से, ऐसा लगता है कि यह EXPLAINअपने आप में यह जानना पर्याप्त नहीं है कि क्या वास्तव में एक इंडेक्स रीचेक आवश्यक होगा क्योंकि बिट आईडी के ढेर स्कैन के दौरान कुछ पंक्ति आईडी को पृष्ठों को बनाए रखने के पक्ष में गिराया जा रहा है।

उपयोग करना EXPLAIN ANALYZEमध्यम लंबाई के प्रश्नों के साथ मुद्दों के निदान के लिए ठीक है, लेकिन इस मामले में कि एक क्वेरी को पूरा करने के लिए एक बहुत लंबा समय लग रहा है, फिर EXPLAIN ANALYZEयह पता लगाने के लिए कि आपका बिटमैप इंडेक्स अपर्याप्त होने के कारण हानिपूर्ण में परिवर्तित हो रहा work_memहै, अभी भी एक कठिन बाधा है। काश EXPLAIN, टेबल आँकड़ों से इस घटना की संभावना का अनुमान लगाने का एक तरीका होता ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.