जब एक संग्रहीत कार्यविधि में एड-हॉक बनाम कोड चलाया जाता है तो कोड अलग योजना बनाता है


9

मेरे पास एक डिलीट स्टेटमेंट है जो एक स्टोर किए गए प्रोसेस के अंदर चलने पर एक खराब प्लान का उपयोग कर रहा है, लेकिन एड-हॉक चलाने पर बहुत बेहतर प्लान चुन रहा है।

मैंने क्वेरी द्वारा उपयोग की जाने वाली तालिकाओं के लिए सभी अनुक्रमितों को फिर से बनाया है और सभी कैश को गिरा दिया है। आशावादी अभी भी संग्रहीत कार्यविधि के लिए गलत योजना चुनता है।

मैं यह जानना चाहूंगा कि क्यों अनुकूलक एड-हॉक SQL बनाम संग्रहीत कार्यविधि के लिए एक अलग निष्पादन योजना का उपयोग कर रहा है।

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

समाधान: मैंने UNKNOWN संकेत के लिए OPTIMIZE का उपयोग करके अपनी इच्छित योजना प्राप्त करना समाप्त कर दिया।


यह शायद सूँघने का पैरामीटर है । क्या क्वेरी इसके WHEREखंड में परिवर्तनशील है ?
निक चामास ऑक्ट

4
क्या आप कृपया कोड जोड़ सकते हैं
gbn

कृपया योजनाओं को भी कहीं पोस्ट करें। जैसा कि, आपको यह बताने में बहुत मुश्किल होने वाली है कि योजनाएं अलग-अलग क्यों हैं।
हारून बर्ट्रेंड

ठीक है, अधिक जानकारी: मैं योजनाओं और कोड को तब तक पोस्ट नहीं कर सकता जब तक कि मैं उन्हें थोड़ा सा भी बाधित नहीं करता। मैं उन्हें कुछ में लाने की कोशिश करूँगा। संग्रहित प्रक्रिया (खराब) की योजना एक बड़ी तालिका (पूरी बात, सभी विभाजन) की एक क्लस्टर इंडेक्स स्कैन करती है। यह तब एक छोटी तालिका से पंक्तियों को खोजने के लिए एक लूप का उपयोग करता है, और फिर छोटी तालिका से हटाता है।
संदेशवाद

तदर्थ कोड (अच्छा) के लिए योजना छोटी तालिका (जिसमें केवल 5-10 पंक्तियाँ हैं) की एक तालिका स्कैन करती है और बड़ी तालिका के गैर-संकुलित सूचकांक का उपयोग करती है ताकि यह पता लगाया जा सके कि उसे पीके में कौन सी पंक्तियों की जाँच करनी है। बड़ी तालिका का। मैं जितनी जल्दी हो सके वास्तविक योजनाओं को प्राप्त करने की कोशिश करूँगा।
१२:३१ पर १२

जवाबों:


5

हमेशा की तरह संदिग्ध:

  1. एडहॉक में स्थिरांक, कोड में पैरामीटर
  2. कोड में डेटा प्रकारों का बेमेल
  3. पैरामीटर सूँघ रहा है

बिंदु 1: ऑप्टिमाइज़र स्थिरांक के लिए सबसे अच्छी योजना चुन सकता है।
स्थिरांक बदलना = योजना बदलना। एक पैरामाइज्ड प्लेन रिजुवेबल है

बिंदु 2 डेटा रूपांतरण की वजह से निहित रूपांतरणों को पेश करेगा
जैसे कि nvarchar पैरामीटर की तुलना में varchar स्तंभ

बिंदु 3: उपयोग के लिए पैरामीटर मास्किंग या ऑप्टिमाइज़
करें UNKNOWN के लिए संपादित करें: परीक्षण करने के लिए: संग्रहित खरीदारी चलाएँ, sp_updatestats चलाएँ, फिर से चलाएँ। यह कैश की गई योजनाओं को अमान्य कर देगा, जो तब की योजना कैश को बेहतर करना है

संपादित करें: jcolebrand की टिप्पणी के बाद

आप कई तरीकों से सूँघने को निष्क्रिय कर सकते हैं। मुख्य 3 हैं

  • पुनः संकलित करें। यह मूर्खतापूर्ण IMO है।
  • UNKNOWN के लिए OPTIMIZE (sic)
  • पैरामीटर मास्किंग

पैरामीटर मास्किंग:

DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam

SELECT...WHERE column = @MaskedParam

मास्किंग और ऑप्टिमाइज हिंट का एक ही प्रभाव है (शायद अलग-अलग कारणों से)। यही है, आशावादी को सांख्यिकी और डेटा वितरण का उपयोग करना होगा ( नोट: अभी भी मार्क स्टोरी-स्मिथ द्वारा परीक्षण के तहत ) अपनी स्वयं की योग्यता के मापदंडों का मूल्यांकन करते हैं ? , बजाय इसके कि वे अंतिम कॉल क्या थे। आशावादी पुनर्मिलन कर सकता है या नहीं। SQL सर्वर 2005 ने स्टेटमेंट लेवल recompilation जोड़ा ताकि कम प्रभाव पड़े

अब, नकाबपोश / "अज्ञात" मापदंडों की तुलना में "सूंघ" मापदंडों के साथ एक योजना "चिपचिपा" क्यों है, मुझे यकीन नहीं है।

मैंने SQL सर्वर 2000 के बाद से सभी सरलतम कोड के लिए पैरामीटर मास्किंग का उपयोग किया है। मैंने नोट किया है कि यह अधिक जटिल कोड के साथ होने के लिए उत्तरदायी है। और अपनी पुरानी नौकरी में मेरे पास कुछ रिपोर्ट है जो कहती है कि मैं योजना के मापदंडों को बदल सकता हूं। मुझे लगता है कि "कार्गो पंथ" दृष्टिकोण समर्थन कॉल की तुलना में आसान था।

कुछ चैट के बाद 2, 12 अक्टूबर 2011 को संपादित करें

  • पैरामीटर मास्किंग और ऑप्टिमाइज़ फॉर UNKNOWN का वही प्रभाव है जहाँ तक मैं बता सकता हूँ कि
    संकेत मास्किंग की तुलना में क्लीनर है लेकिन SQL सर्वर 2008 के साथ जोड़ा गया था।

  • कम्पाइलर सूँघने का संकलन समय पर होता है।
    RECOMPILE के साथ प्रत्येक निष्पादन के लिए एक नई योजना तैयार करता है। इसका मतलब यह है कि चूक का एक खराब विकल्प योजना को प्रभावित करेगा। अपनी अंतिम नौकरी में, मैं इसे आसानी से कुछ रिपोर्ट कोड के साथ प्रदर्शित कर सकता था: बदलते पैरामीटर चूक ने आपूर्ति के मापदंडों की परवाह किए बिना योजना को बदल दिया।

  • यह एमएस कनेक्ट लेख दिलचस्प है: संग्रहीत कार्यविधि के भीतर उप-दांतेदार सूचकांक उपयोग (नीचे दिए गए SO उत्तरों में से एक में उल्लिखित)

  • बॉब बेउचेमिन ने भी इसका उल्लेख किया है

बकाया मुद्दे

  • क्या सूँघना अभी भी RECOMPILE के साथ लागू होता है? यही है, अगर आशावादी जानता है कि योजना को त्यागना क्या इसका उद्देश्य फिर से उपयोग करना है?

  • क्यों सूँघते हैं योजनाएँ "चिपचिपी"?

एसओ से लिंक:


1. सपा में परम कोड 2 में एक चर है। फिर से, एक ही डेटाटाइप 3. मैंने कई प्रकार के मापदंडों के साथ चलाया है, और मुझे हर बार एक ही योजना मिलती है। मैंने प्रत्येक प्रयास के बाद कैश को साफ़ किया।
१२:

1
पुन: बिंदु 3. आप मौजूदा योजनाओं की अवहेलना करने के लिए एसक्यूएल सर्वर को मजबूर करने के लिए OPTION (RECOMPILE)या पूरी खरीद के साथ बयान भी चला सकते हैं WITH RECOMPILE
निक चम्मास

3
BTW यह है OPTIMIZE, क्योंकि Microsoft एक अमेरिकी कंपनी है। :)
निक चम्मास

1
@ गबन को रोकने / पराजित करने वाले पैरामीटर पर कोई विचार?
jcolebrand

1
@jcolebrand: सरल उत्तर "नहीं" है :-)
gbn

2

यह न भूलें कि कनेक्शन योजना के लिए आपके पास जो ANSI सेटिंग्स हैं, वे निष्पादन योजना चयन में भूमिका निभाती हैं। जब एप्लिकेशन संग्रहीत कार्यविधि को कॉल करता है तो संभवतः आपके SSMS कनेक्शन की तुलना में अलग ANSI सेटिंग्स होती हैं।

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