मैंने आज एक घंटे से अधिक समय बिताया एक प्रश्न योजना पर खुद को परेशान कर रहा था जिसे मैं समझ नहीं पाया। क्वेरी UDPATE
थी और यह बस सभी को नहीं चलाएगी। पूरी तरह से deadlocked: pg_locks
दिखाया कि यह किसी भी चीज़ के लिए इंतजार नहीं कर रहा था। अब, मैं खुद को सबसे अच्छा या सबसे खराब क्वेरी प्लान रीडर लड़का नहीं मानता, लेकिन मुझे यह एक असाधारण मुश्किल लगता है। मैं सोच रहा हूं कोई इन्हें कैसे पढ़ता है? क्या कोई ऐसी पद्धति है जो त्रुटि को इंगित करने के लिए पीजी एसेस का पालन करती है?PostgreSQL क्वेरी योजना पढ़ने पर मैं "बेहतर सोच सकता हूं" कैसे? (उदाहरण संलग्न)
मैं इस मुद्दे के आसपास काम करने के तरीके के बारे में एक और सवाल पूछने की योजना बना रहा हूं, लेकिन अभी मैं विशेष रूप से पर बात कर रहा हूं कि इन प्रकार की योजनाओं को कैसे पढ़ा जाए। कृपया किसी भी सामान्य ट्यूटोरियल को इंगित न करें जब तक कि यह विशेष रूप से इस समस्या को हल न करे, क्वेरी योजना के नीचे हाइलाइट किया गया हो।
QUERY PLAN
--------------------------------------------------------------------------------------------
Nested Loop Anti Join (cost=47680.88..169413.12 rows=1 width=77)
Join Filter: ((co.fkey_style = v.chrome_styleid) AND (co.name = o.name))
-> Nested Loop (cost=5301.58..31738.10 rows=1 width=81)
-> Hash Join (cost=5301.58..29722.32 rows=229 width=40)
Hash Cond: ((io.lot_id = iv.lot_id) AND ((io.vin)::text = (iv.vin)::text))
-> Seq Scan on options io (cost=0.00..20223.32 rows=23004 width=36)
Filter: (name IS NULL)
-> Hash (cost=4547.33..4547.33 rows=36150 width=24)
-> Seq Scan on vehicles iv (cost=0.00..4547.33 rows=36150 width=24)
Filter: (date_sold IS NULL)
-> Index Scan using options_pkey on options co (cost=0.00..8.79 rows=1 width=49)
Index Cond: ((co.fkey_style = iv.chrome_styleid) AND (co.code = io.code))
-> Hash Join (cost=42379.30..137424.09 rows=16729 width=26)
Hash Cond: ((v.lot_id = o.lot_id) AND ((v.vin)::text = (o.vin)::text))
-> Seq Scan on vehicles v (cost=0.00..4547.33 rows=65233 width=24)
-> Hash (cost=20223.32..20223.32 rows=931332 width=44)
-> Seq Scan on options o (cost=0.00..20223.32 rows=931332 width=44)
(17 rows)
इस क्वेरी योजना के साथ इस मुद्दे - मेरा मानना है कि मैं समझता हूँ - शायद सबसे अच्छा RhodiumToad
द्वारा कहा जाता है (वह निश्चित रूप से इस पर बेहतर है, इसलिए मैं अपने विवरण में बेहतर होने पर दांव लगाया जाएगा) irc://irc.freenode.net/#postgresql
की:
ओह, कि योजना संभावित विनाशकारी है कि योजना के साथ समस्या यह प्रत्येक पंक्ति के लिए एक बेहद महंगा hashjoin चल रहा है वह यह है कि समस्या पंक्तियों = 1 दूसरे से अनुमान में शामिल होने और योजनाकार सोचता है कि यह करने के लिए ठीक है एक विशाल रखो एक nestloop के भीतरी पथ में महंगा महंगी क्वेरी जहां बाहरी पथ केवल एक पंक्ति वापस करने का अनुमान है। , जाहिर है, योजनाकार के अनुमान से महंगा हिस्सा केवल पर चलाया जाएगा, लेकिन यह वास्तव में अभ्यास में गड़बड़ करने की स्पष्ट प्रवृत्ति है, समस्या यह है कि योजनाकार का मानना है कि इसका अनुमान आदर्श है, योजनाकार को यह जानने की आवश्यकता है के बीच का अंतर और "संभव नहीं 1 से अधिक पंक्ति लौटने के लिए" "1 पंक्ति लौटने का अनुमान" लेकिन यह बिल्कुल स्पष्ट है कि कैसे मौजूदा कोड
वह आगे कहते हैं कि शामिल करने के लिए नहीं है:
यह किसी भी शामिल होने को प्रभावित कर सकता है, लेकिन आमतौर पर इसके खिलाफ जुड़ता है सबक्वेरी अब सबसे अधिक संभावना
हैं जब मैं इस योजना पहली बात मैंने देखा Nested Loop Anti Join
था पढ़ा है, यह (मैं ऊपरी सीमा को रह सकते हैं) 169,413
की लागत से किया था। यह एंटी-जॉइन Nested Loop
के परिणामस्वरूप 31,738
की लागत पर के परिणाम पर Hash Join
के परिणामस्वरूप टूट गया है। अब, 137,424
, 31,738
से अधिक है इसलिए मुझे पता था कि समस्या हैश जॉइन थी। फिर मैं प्रश्न के बाहर हैश जॉइन सेगमेंट EXPLAIN ANALYZE
पर आगे बढ़ता हूं। यह 7 सेकंड में निष्पादित किया गया। मैंने सुनिश्चित किया कि इंडेक्स (lot_id, vin), और (co.code, और v.code) पर था - वहां था। मैंने seq_scan
और hashjoin
को व्यक्तिगत रूप से अक्षम कर दिया और 2 सेकंड से भी कम की गति वृद्धि देखी। इस बात के लिए पर्याप्त नहीं है कि यह एक घंटे के बाद क्यों प्रगति नहीं कर रहा था।
लेकिन, इसके बाद मैं पूरी तरह गलत हूं! हां, यह क्वेरी का धीमा हिस्सा था, लेकिन rows="1"
बिट (मुझे लगता है कि यह Nested Loop Anti Join
पर था)। क्या कोई ट्यूटोरियल है जो मुझे इस तरह के मुद्दों की पहचान करने में मदद करेगा। यहां योजनाकार में पंक्तियों की मात्रा का गलत अनुमान लगाने की क्षमता में एक बग (क्षमता की कमी) है?RhodiumToad
ने उसी निष्कर्ष पर आने के लिए इसे कैसे पढ़ा है?
क्या यह बस rows="1"
है जो मुझे यह पता लगाने के लिए ट्रिगर करने वाला है?
मैंने शामिल सभी तालिकाओं पर VACUUM FULL ANALYZE
चलाया, और यह पोस्टग्रेस्क्ल 8.4 है।
यह एक अच्छा जवाब है, लेकिन जब आप 'सह में शामिल होने' कहते हैं तो आप किसके बारे में बात कर रहे हैं? मुझे लगता है कि समस्या का 'रोडियाडोड्स' स्पष्टीकरण क्योंकि यह सटीक लगता है? क्या आप एक ही चीज़ या कुछ अलग बता रहे हैं? –
वही बात। 'सह' में शामिल होना 'नेस्टेड लूप में शामिल होने के विकल्प co' के आंतरिक नोड पर विकल्प_पीकी का उपयोग करके इंडेक्स स्कैन है। इसमें दो स्थितियां हैं जिनकी योजनाकार शायद अवास्तविक रूप से सोचता है, परिणामस्वरूप आउटपुट की एक पंक्ति होगी।यदि आप उस क्वेरी को चलाने का प्रयास करते हैं और देखते हैं कि वास्तव में कितनी पंक्तियां आती हैं तो आप यह सत्यापित कर सकते हैं कि यह मामला है या नहीं। सहसंबंधित भविष्यवाणियों के लिए खराब अनुमान एक ज्ञात मुद्दा हैं। प्रदर्शन सूची पर इसके बारे में कुछ चर्चाएं हैं: http://archives.postgresql.org/pgsql-performance/2009-06/msg00055.php –