24

को समझने के लिए कैसे मैं एक्सप्लोर विश्लेषण परिणामों को देखने से बहुत परिचित नहीं हूं, मुझे अपने प्रश्नों के साथ बहुत धीमी समस्या है। मैंने एक व्याख्या प्रश्नों के परिणामों की व्याख्या करने के तरीके को पढ़ने की कोशिश की है, लेकिन मुझे अभी भी पता नहीं है कि मुझे क्या देखना चाहिए, और क्या गलत हो सकता है। मुझे एहसास है कि कहीं भी कुछ बड़ी लाल रोशनी चमकती है, मुझे बस यह नहीं दिख रहा है।एक EXPLAIN ANALYZE

तो क्वेरी बहुत सरल है, यह वह ऐसा दिखता है:

EXPLAIN ANALYZE SELECT "cars".* FROM "cars" WHERE "cars"."sales_state" = 'onsale' AND "cars"."brand" = 'BMW' AND "cars"."model_name" = '318i' AND "cars"."has_auto_gear" = TRUE LIMIT 25 OFFSET 0 

और इस तरह परिणाम:

Limit (cost=0.00..161.07 rows=25 width=1245) (actual time=35.232..38.694 rows=25 loops=1) 
    -> Index Scan using index_cars_onsale_on_brand_and_model_name on cars (cost=0.00..1179.06 rows=183 width=1245) (actual time=35.228..38.652 rows=25 loops=1) 
     Index Cond: (((brand)::text = 'BMW'::text) AND ((model_name)::text = '318i'::text)) 
     Filter: has_auto_gear" 
Total runtime: 38.845 ms 

एक छोटी सी पृष्ठभूमि: मैं Postgresql 9.1.6 पर हूँ, हेरोोकस समर्पित डेटाबेस पर चल रहा है। मेरे डीबी में लगभग 7,5 जीबी रैम है, टेबल कारों में 3,1 एम पंक्तियां हैं और पंक्तियों के एक aprox 2,0M में sales_state = 'onsale' है। तालिका में 170 कॉलम हैं। इंडेक्स जो इसका उपयोग करता है वह इस तरह दिखता है:

CREATE INDEX index_cars_onsale_on_brand_and_model_name 
    ON cars 
    USING btree 
    (brand COLLATE pg_catalog."default" , model_name COLLATE pg_catalog."default") 
    WHERE sales_state::text = 'onsale'::text; 

कोई भी कुछ स्पष्ट स्पष्ट मुद्दा देख रहा है?

संपादित करें:

SELECT pg_relation_size('cars'), pg_total_relation_size('cars'); 

pg_relation_size: +२०५८४४४८०० pg_total_relation_size: 4900126720

SELECT pg_relation_size('index_cars_onsale_on_brand_and_model_name'); 

pg_relation_size: 46301184

SELECT avg(pg_column_size(cars)) FROM cars limit 5000; 

का औसत: 636,9732567210792995

सीमा के बिना:

EXPLAIN ANALYZE SELECT "cars".* FROM "cars" WHERE "cars"."sales_state" = 'onsale' AND "cars"."brand" = 'BMW' AND "cars"."model_name" = '318i' AND "cars"."has_auto_gear" = TRUE 

Bitmap Heap Scan on cars (cost=12.54..1156.95 rows=183 width=4) (actual time=17.067..55.198 rows=2096 loops=1) 
    Recheck Cond: (((brand)::text = 'BMW'::text) AND ((model_name)::text = '318i'::text) AND ((sales_state)::text = 'onsale'::text)) 
    Filter: has_auto_gear 
    -> Bitmap Index Scan on index_cars_onsale_on_brand_and_model_name (cost=0.00..12.54 rows=585 width=0) (actual time=15.211..15.211 rows=7411 loops=1)" 
     Index Cond: (((brand)::text = 'BMW'::text) AND ((model_name)::text = '318i'::text)) 
Total runtime: 56.851 ms 
+0

सफाई का प्रयास करें - http://www.postgresql.org/docs/8.1/static/maintenance.html। क्वेरी योजना उचित दिखती है, लेकिन समय निश्चित रूप से नहीं करता है! –

+0

प्रश्न पूछने से ठीक पहले, मैंने एक पूर्ण वैक्यूम और एक विश्लेषण भी चलाया ... मेरी वेबसाइट प्रयुक्त कारों के लिए एक खोज इंजन है, इसलिए समय बहुत अस्वीकार्य है। मेरा लक्ष्य कुल समय को 1 सेकंड से कम तक प्राप्त करना है। क्या आपको लगता है कि यह संभव है, या मुझे एक तर्कसंगत डेटाबेस की तुलना में एक अलग तकनीक की तलाश करनी होगी? –

+0

@ नील्स क्रिस्टियन मुझे लगता है कि समस्या का एक बड़ा हिस्सा "170 कॉलम" भाग हो सकता है। टेबल कितनी बड़ी है? 'चुनें pg_relation_size (' कार '), pg_total_relation_size (' कार '); '। इसके अलावा 'सूचकांक आकार प्राप्त करने के लिए' pg_relation_size ('index_cars_onsale_on_brand_and_model_name') चुनें; औसत पंक्ति चौड़ाई क्या है? 'चयन करें औसत (pg_column_size (कारें)) परीक्षण कारों से 5000 की सीमा; ' –

उत्तर

22

जबकि इस तरह एक सरल योजना के लिए के रूप में उपयोगी नहीं, http://explain.depesz.com वास्तव में उपयोगी है। http://explain.depesz.com/s/t4fi देखें। "आंकड़े" टैब और "विकल्प" pulldown नोट करें।

हालात इस योजना के बारे में गौर करने योग्य

  • अनुमान पंक्ति संख्या (183) यथोचित वास्तविक पंक्ति संख्या (25) के बराबर है। यह सैकड़ों गुना अधिक नहीं है, न ही यह है 1. जब आप पंक्ति गणना अनुमानों, या "1 बनाम 1" मुद्दों की बात आती है तो आप परिमाण के आदेश में अधिक रुचि रखते हैं। (आपको "सरकारी काम के लिए पर्याप्त निकटता" की आवश्यकता भी नहीं है - "सैन्य अनुबंध लेखांकन के लिए पर्याप्त बंद करें" करेंगे)। चुनिंदाता अनुमान और आंकड़े उचित लगते हैं।

  • यह दो कॉलम आंशिक अनुक्रमणिका (index scan using index_cars_onsale_on_brand_and_model_name) का उपयोग कर रहा है, इसलिए यह आंशिक अनुक्रमणिका स्थिति से मेल खाता है। आप देख सकते हैं कि Filter: has_auto_gear में। इंडेक्स सर्च हालत भी दिखाया गया है।

  • क्वेरी प्रदर्शन उचित दिखता है कि तालिका की पंक्ति गणना का मतलब यह होगा कि सूचकांक काफी बड़ा है, खासकर जब यह दो कॉलम से अधिक है। मिलान पंक्तियां बिखरी जाएंगी, इसलिए संभव है कि प्रत्येक पंक्ति को एक अलग पृष्ठ को भी पढ़ने की आवश्यकता होगी।

मुझे यहां कुछ भी गलत नहीं दिख रहा है। यह क्वेरी पोस्टग्रेएसक्यूएल 9.2 के इंडेक्स-केवल स्कैन से काफी लाभान्वित होगी, हालांकि।

यह संभव है कि यहां कुछ टेबल ब्लोट है, लेकिन 2-कॉलम इंडेक्स और पंक्तियों की निचली संख्या को देखते हुए प्रतिक्रिया समय पूरी तरह से अनुचित नहीं है, खासतौर पर 170 (!!) कॉलम वाली तालिका के लिए जो अपेक्षाकृत फिट होने की संभावना है प्रत्येक पृष्ठ में कुछ tuples। यदि आप कुछ डाउनटाइम पर खर्च कर सकते हैं तो तालिका को पुनर्गठित करने और इंडेक्स का पुनर्निर्माण करने के लिए VACUUM FULL आज़माएं। जब यह इसे पुनर्निर्माण करता है तो यह विशेष रूप से तालिका को कुछ समय तक लॉक कर देगा। यदि आप डाउनटाइम पर बर्दाश्त नहीं कर सकते हैं, तो pg_reorg और/या CREATE INDEX CONCURRENTLY और ALTER INDEX ... RENAME TO देखें।

आप EXPLAIN (ANALYZE, BUFFERS, VERBOSE) अधिक कभी कभी जानकारीपूर्ण मिल सकती है, के रूप में यह बफर तक पहुँचता है दिखा सकते हैं, आदि

एक विकल्प (हालांकि यह अन्य प्रश्नों के कुछ हद तक धीमा होने का खतरा चलता है) कि इस क्वेरी तेजी से कर सकते हैं तालिका विभाजन है brand पर और constraint_exclusion सक्षम करें। partitioning देखें।

+0

हाय, आपकी स्पष्टीकरण के लिए धन्यवाद, प्रश्न पूछने से ठीक पहले, मैंने एक पूर्ण वैक्यूम किया –

+0

@Niels क्रिस्टियन विभाजन पर विचार करें सब कुछ विफल रहता है; जवाब देने के लिए संपादन देखें। साथ ही, 'एक्सप्लाइन (विश्लेषण, बफर, वर्बोज़)' परिणाम दिखाने के लिए अपने प्रश्न को संपादित करने पर विचार करें। –

+0

सभी महान मदद के लिए धन्यवाद! मुझे निश्चित रूप से एसक्यूएल डीबग करने के बारे में बहुत कुछ जानकारी मिली है। समाधान तालिका में कॉलम की संख्या को कम करने के लिए निकला है, और जो भी मैं चुनता हूं उस पर अधिक सटीक होना। दूसरी बात मैंने कुछ बेहतर फिटिंग इंडेक्स बनाए हैं। –

0

अच्छा ... पहली बात यह है कि मैं आपको बता सकता हूं कि आपका डेटाबेस 183 पंक्तियों के लिए (आंकड़ों से) उम्मीद कर रहा है। हकीकत में यह 25 पंक्तियां प्राप्त कर रहा है। यद्यपि यह शायद इस मामले में बहुत प्रासंगिक नहीं है (यानी इन छोटी मात्राओं और कोई भारी परिचालन के साथ, इसे गलत तरीके से अनुमान लगाने की चिंता करने की आवश्यकता नहीं है)।

एक बड़ी समस्या (imho) यह है कि 25 पंक्तियों के लिए एक साधारण इंडेक्स लुकअप 35ms ले रहा है। यह थोड़ा सा लगता है। क्या डाटाबेस कम से कम सभी इंडेक्स मेमोरी में पर्याप्त है? हालांकि यह अत्यधिक नहीं है, बस मेरे लिए थोड़ा धीमा लगता है।

अपने बताते हैं पर देख रहे हैं के लिए के रूप में, मैं explain.depesz.com का उपयोग कर की सिफारिश करेंगे: http://explain.depesz.com/s/sA6

+0

क्या आपका मतलब 35 नहीं है? –

+0

@Niels क्रिस्टियन मुझे मिलीसेकंड की तरह दिखता है। अनुमान में आप इसे डीई शैली नोटेशन में पढ़ रहे हैं, उदाहरण के लिए यूएस/एयू/यूके शैली "123,456,789.50" के बजाय "123.456.789,50"। AFAIK PG EXPLAIN विश्लेषण में समय को स्थानीयकृत नहीं करता है, इसलिए यह 35 मिलीसेकंड होना चाहिए। –

संबंधित मुद्दे