2012-02-14 15 views
6

PostgreSQL में, कब (चयन) प्रश्न योजनाबद्ध हैं?कब (चयन) प्रश्न योजनाबद्ध हैं?

यह है:-तैयार बयान के समय, या चयन के प्रसंस्करण के शुरू में

  • , वरना
  • कुछ कारण मैं पूछता हूँ कि है पर

    1. वहाँ एक स्टैक ओवरफ्लो प्रश्न है: same query, two different ways, vastly different performance

      बहुत से लोग सोच रहे हैं कि टी वह क्वेरी अलग-अलग योजनाबद्ध है क्योंकि एक मामले में क्वेरी में स्ट्रिंग अक्षर ('foo') होता है और दूसरे मामले में यह प्लेसहोल्डर (?) होता है।

      अब मेरी सोच यह है कि यह एक लाल हेरिंग है, क्योंकि कथन तैयार समय पर क्वेरी की योजना नहीं है, लेकिन वास्तव में चयन समय पर योजना बनाई गई है।

      तो, कहें, मैं प्लेसहोल्डर के साथ एक कथन तैयार कर सकता हूं, फिर अलग-अलग बाध्य मानों के साथ क्वेरी को कई बार चला सकता हूं, और क्वेरी प्लानर प्रत्येक अलग-अलग बाध्य मान के लिए चलाया जाएगा।

      मुझे लगता है कि question linked above मूल्य की PostgreSQL डेटा प्रकार है, जो एक 'foo' शाब्दिक के मामले में एक स्ट्रिंग माना जाता है करने पर निर्भर करता है, लेकिन एक प्लेसहोल्डर के मामले में, प्रकार divined नहीं किया जा सकता , इसलिए प्रश्न योजनाकार के माध्यम से कुछ अजीब प्रकार के रूप में आ रहा है, जिसके लिए यह एक कुशल योजना नहीं बना सकता है। इस मामले में, मुद्दा यह नहीं है कि क्वेरी को अलग-अलग योजनाबद्ध किया जा रहा है क्योंकि मान प्लेसहोल्डर (स्टेटमेंट तैयारी समय पर) प्रति से है लेकिन यह मान क्वेरी के माध्यम से एक अलग PostgreSQL प्रकार, और के रूप में आ रहा है क्वेरी प्लानर को प्रभावित कर रहा है। इसे ठीक करने के लिए प्लेसहोल्डर को उचित स्पष्ट प्रकार की घोषणा के साथ बाध्य करने का मामला होगा।

  • +1

    अच्छा सवाल! यह बहुत डीबीएमएस-विशिष्ट है; अलग-अलग डीबीएमएस अलग-अलग उत्तरों के साथ आते हैं। शुद्ध परिणाम नाटकीय रूप से अलग हो सकता है। इनफॉर्मिक्स एक 'खुला कर्सर उपयोग कर रहा है ... REOPTIMIZATION' का समर्थन करता है जिसे SQL को दोबारा नहीं करना पड़ता है (जो समय बचाता है) लेकिन पैरामीटर के वर्तमान सेट के लिए क्वेरी प्लान को फिर से करता है। यह ज्यादातर डीबीएमएस से अलग है। –

    +0

    हां। यह सवाल आश्चर्यजनक रूप से विवादास्पद साबित हो रहा है।हमारे पास उपरोक्त प्रश्न और उत्तर में से एक है और उत्तर में से एक है। – zgpmax

    +0

    @ होचगर्गलर: टाइप मिस्चैच के बारे में आपका संदेह स्वयं ही एक वैध चिंता है, PostgreSQL _has_ यहां कुछ ज्ञात समस्याएं हैं। लेकिन सवाल के पहले भाग पर विचार करते हुए मुझे लगता है कि इन दो मुद्दों को मिश्रित नहीं किया जाना चाहिए और दूसरे भाग को एक अलग प्रश्न से बेहतर तरीके से संभाला जाएगा। क्या आप इसे विभाजित करेंगे? –

    उत्तर

    10

    मैं क्लाइंट-साइड पर्ल इंटरफ़ेस के बारे में बात नहीं कर सकता लेकिन मैं PostgreSQL सर्वर पक्ष पर कुछ प्रकाश डाल सकता हूं।

    पोस्टग्रेएसक्यूएल ने बयान और तैयार किए गए बयान तैयार किए हैं। अप्रत्याशित बयानों को पार्स किया गया है, योजनाबद्ध और तुरंत निष्पादित किया गया है। वे समर्थन पैरामीटर प्रतिस्थापन भी करते हैं। दूसरी ओर

    tmpdb> explain select * from sometable where flag = true; 
    

    वहाँ तैयार बयान कर रहे हैं: एक सादे psql खोल पर आप इस तरह उनके क्वेरी योजना को दिखा सकते हैं वे आम तौर पर कर रहे हैं (देखें "अपवाद" नीचे) पार्स और एक कदम में योजना बनाई है और एक में मार डाला दूसरा कदम। उन्हें विभिन्न मानकों के साथ कई बार फिर से निष्पादित किया जा सकता है, क्योंकि वे समर्थन पैरामीटर प्रतिस्थापन करते हैं।

    tmpdb> prepare foo as select * from sometable where flag = $1; 
    tmpdb> explain execute foo(true); 
    

    आप देख सकते हैं, कि योजना तैयार नहीं बयान में योजना से अलग है, क्योंकि नियोजन पहले से ही जगह ले था prepare चरण में PREPARE के लिए दस्तावेज़ में वर्णित के रूप में:

    psql में बराबर यह है

    जब तैयार बयान निष्पादित किया जाता है, निर्दिष्ट बयान पार्स, पुनः, और योजना बनाई है। जब एक EXECUTE कमांड बाद में जारी किया गया है, तो तैयार कथन को केवल निष्पादित करने की आवश्यकता है। इस प्रकार, पार्सिंग, पुनर्लेखन और नियोजन चरणों को केवल एक बार किया जाता है, प्रत्येक बार जब कथन निष्पादित किया जाता है।

    यह भी मतलब है, उस योजना नहीं प्रतिस्थापित मानकों के लिए अनुकूलित है: पहला उदाहरण में flag के लिए एक सूचकांक का उपयोग कर सकते क्योंकि PostgreSQL जानता है कि एक लाख प्रविष्टियों के भीतर केवल दस मूल्य true है। यह तर्क असंभव है जब PostgreSQL एक तैयार कथन का उपयोग करता है। उस स्थिति में एक योजना बनाई जाती है जो संभवतः जितना संभव हो सके सभी संभावित पैरामीटर मानों के लिए काम करेगी। यह हो सकता है कि उल्लिखित अनुक्रमणिका को बाहर कर दें क्योंकि यादृच्छिक पहुंच (इंडेक्स के कारण) के माध्यम से पूर्ण तालिका का बेहतर हिस्सा लाने से सादे अनुक्रमिक स्कैन की तुलना में धीमी गति हो जाती है। PREPARE दस्तावेज़ की पुष्टि करता है यह:

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

    तैयार बयान केवल वर्तमान डेटाबेस सत्र की अवधि के लिए पिछले: -

    BTW योजना PREPARE दस्तावेज़ भी कैशिंग के बारे में कहने के लिए कुछ नहीं है। जब सत्र समाप्त होता है, तैयार कथन भूल जाता है, इसलिए इसे दोबारा उपयोग करने से पहले पुनर्निर्मित किया जाना चाहिए।

    इसके अलावा कोई स्वचालित योजना कैशिंग नहीं है और एकाधिक कनेक्शन पर कोई कैशिंग/पुन: उपयोग नहीं है।

    EXCEPTION: मैंने "आमतौर पर" उल्लेख किया है। दिखाया गया psql उदाहरण क्लाइंट एडाप्टर नहीं हैं जैसे कि पर्ल डीबीआई वास्तव में उपयोग करता है। यह एक निश्चित protocol का उपयोग करता है। यहां "सरल क्वेरी" शब्द psql में "तैयार प्रश्न" से मेल खाता है, "extended query" शब्द एक अपवाद के साथ "तैयार क्वेरी" से मेल खाता है: (एक) "अज्ञात कथन" और (संभवतः एकाधिक) के बीच एक अंतर है " नामित बयान "। नामित बयान के बारे में doc का कहना है:

    नाम से तैयार बयान भी बनाया जा सकता है और SQL आदेश के स्तर पर पहुँचा, तैयार और निष्पादित इस्तेमाल करते हैं।

    और यह भी: नामित तैयार बयान वस्तुओं के लिए

    क्वेरी की योजना बना तब होता है जब पार्स संदेश संसाधित किया जाता है।

    तो इस मामले में योजना PREPARE के लिए ऊपर वर्णित पैरामीटर के बिना की जाती है - कुछ नया नहीं।

    उल्लेख किया गया अपवाद "अज्ञात कथन" है। दस्तावेज़ कहते हैं:

    अनाम तैयार बयान वैसे ही पार्स प्रसंस्करण दौरान योजना बनाई है अगर पार्स संदेश कोई पैरामीटर परिभाषित करता है। लेकिन यदि पैरामीटर हैं, तो प्रत्येक बार बाइंड पैरामीटर की आपूर्ति की जाती है, क्वेरी प्लानिंग होती है। यह योजनाकार जेनेरिक अनुमानों के बजाय, प्रत्येक बाइंड संदेश द्वारा प्रदत्त मानकों के वास्तविक मूल्यों का उपयोग करने की अनुमति देता है।

    और यहां लाभ है: हालांकि अनाम नाम "तैयार" है (यानी पैरामीटर प्रतिस्थापन हो सकता है), यह वास्तविक पैरामीटर को क्वेरी प्लान को भी अनुकूलित कर सकता है।

    बीटीडब्ल्यू: अज्ञात कथन की सटीक हैंडलिंग पोस्टग्रेएसक्यूएल सर्वर की पिछली रिलीज में कई बार बदल गई है। यदि आप वास्तव में चाहते हैं तो आप विवरण के लिए पुराने दस्तावेज़ देख सकते हैं।

    दलील - पर्ल/किसी भी ग्राहक:

    कैसे एक ग्राहक पर्ल की तरह प्रोटोकॉल का उपयोग करता है एक पूरी तरह से अलग सवाल है। जावा के लिए जेडीबीसी ड्राइवर जैसे कुछ क्लाइंट मूल रूप से कहते हैं: यहां तक ​​कि यदि प्रोग्रामर तैयार कथन का उपयोग करता है, तो पहले पांच (या तो) निष्पादन आंतरिक रूप से "सरल क्वेरी" (यानी प्रभावी रूप से तैयार नहीं) पर मैप किए जाते हैं, उसके बाद चालक " नामित बयान "।

    • बल (फिर से) "सरल क्वेरी" प्रोटोकॉल का उपयोग करके हर बार की योजना बना:

      तो एक ग्राहक इन विकल्पों है।

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

    वर्तमान में पर्ल क्या करता है: मुझे नहीं पता। लेकिन उल्लेख किया गया "लाल हेरिंग" बहुत ही असंभव नहीं है।

    +0

    +1 लेकिन अधिक मूल्यवान! –

    +0

    +1 बहुत जानकारीपूर्ण। –

    +0

    सेमी-अपडेट: संस्करण 9.2 के बाद से योजना थोड़ा अलग है। वास्तविक पैरामीटर का उपयोग करके प्रत्येक आमंत्रण के लिए मूल रूप से तैयार प्रश्नों की भी योजना बनाई जाएगी। कई आविष्कारों के बाद ही साबित हुआ है कि योजनाएं अलग नहीं हैं, एक सामान्य योजना का उपयोग किया जाता है। –

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