Sp_executesql क्वेरी योजना को कब रिफ्रेश करती है?


13

आपको मेरी भोली को माफ करना होगा क्योंकि मैं एक डीबीए नहीं हूं, लेकिन मेरी समझ यह है कि समय के साथ एक डेटाबेस परिवर्तन और एक संग्रहीत प्रक्रिया के आंकड़ों को नवीनतम आंकड़ों के साथ तारीख तक की योजना को बनाए रखने के लिए फिर से तैयार किया जाना चाहिए।

यह मानते हुए कि मेरे डेटाबेस में एक संग्रहीत कार्यविधि है जो कि कुछ नियमित अंतराल पर नवीनतम आँकड़ों के विरूद्ध recompiled है , कोड में संग्रहीत प्रक्रिया को अस्तर करने और इसे एक sp_executesqlबयान में लपेटने के क्या निहितार्थ हैं ? क्या मैं उस क्वेरी प्लान की रिफ्रेशिंग खो देता हूं, जो प्रक्रिया के पुनर्संयोजन के हिस्से के रूप में हुआ करता था?

अगर कुछ और है (अनुमति के अलावा) जो मुझे इस बदलाव से पहले विचार करने की आवश्यकता है तो मैं आपकी अंतर्दृष्टि की सराहना करूंगा।

मैंने इसे MSDN पर पढ़ा:

SQL सर्वर क्वेरी ऑप्टिमाइज़र की मौजूदा निष्पादन योजना के साथ नए Transact-SQL स्ट्रिंग का मिलान करने की क्षमता स्ट्रिंग के पाठ में लगातार बदलते पैरामीटर मानों से बाधित होती है, विशेष रूप से जटिल Transact-SQL कथनों में।

इसलिए मैंने जिस इन-लाइन और इन-रैप को बनाने की कोशिश की है, sp_executesqlउसमें स्टोर की गई प्रक्रिया को मानने के कुछ पैरामीटर हैं, क्या यह कहा जाता है कि यद्यपि मेरी निष्पादन योजना कैश की गई है, मैं SQL सर्वर के लिए इसे ढूंढना और पुन: उपयोग करना अधिक कठिन बना रहा हूं?

जवाबों:


7

MSDN की रेखा EXEC()इस तरह उपयोग करने के बारे में बात कर रही है :

SET @sql = 'SELECT foo FROM dbo.bar WHERE x = ''' + @x + ''';';
EXEC(@sql);

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

यदि आप उपयोग करते हैं, sp_executesqlतो पैरामीटर मान अभी भी पैरामीटर सूँघने के मुद्दों (सामान्य एसक्यूएल के साथ की तरह) का कारण बन सकता है, लेकिन इसका एसक्यूएल सर्वर योजना का फिर से उपयोग करने से कोई लेना-देना नहीं है। इस योजना को बार-बार उपयोग किया जाएगा, जैसे कि आपने बिल्कुल भी उपयोग नहीं किया था sp_executesql, जब तक कि चर जो प्रत्यक्ष क्वेरी को पुनः प्राप्त करने का कारण नहीं बनेंगे, जिस स्थिति में यह पुनः प्राप्त किया जाएगा (अनिवार्य रूप से, SQL सर्वर नहीं करता है) उस योजना के साथ कुछ भी संग्रहीत करें जो कहती है "यह sp_executesql से निष्पादित किया गया था, लेकिन यह एक नहीं था):

SET @sql = N'SELECT foo FROM dbo.bar WHERE x = @x;';
EXEC sp_executesql @sql, N'@x VARCHAR(32)', @x;

एक बोनस के रूप में, इसने डायनेमिक SQL के खिलाफ अंतर्निहित सुरक्षा प्रदान की है और आपको स्ट्रिंग सीमांकक के कारण सिंगल कोट्स को दोगुना करने की चिंता करने से बचाती है। मैंने यहाँ इसके बारे में कुछ ब्लॉग किया है

आप योजना फिर से उपयोग और / या पैरामीटर सूँघने के साथ मुद्दों कर रहे हैं, तो कुछ चीजें आप इस पर गौर करना चाहिए OPTION (RECOMPILE), OPTIMIZE FOR, optimize for ad hoc workloadsऔर simple/forced parameterization। मैंने हाल ही में एक वेबकास्ट के जवाब में कुछ इसी तरह के सवालों को संबोधित किया, यह एक स्किम के लायक हो सकता है:

http://sqlperformance.com/performance-palooza

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


2

जो क्वेरीज़ sp_executesql के माध्यम से चलाई जाती हैं, वे निष्पादन योजनाओं के सामान्य नियमों का पालन करती हैं, जो sp_executesql के माध्यम से नहीं चलते हैं। यदि क्वेरी पाठ बदलता है तो एक नई योजना बनाई जाती है। यदि पाठ पैरामीटर के उपयोगकर्ता के कारण नहीं बदलता है तो योजना का पुन: उपयोग किया जाता है। जब आँकड़े अपडेट किए जाते हैं तो योजनाएँ समाप्त हो जाती हैं और अगली बार क्वेरी चलाने पर नई योजनाएँ बनती हैं।


आपके उत्तर के लिए धन्यवाद, मैंने मापदंडों के संबंध में एक संपादन किया, जैसा कि मैंने अब महसूस किया है कि हर बार जब मैं sp_ExecuteSql कहता हूं तो मैं एक अलग स्ट्रिंग का उपयोग इस तथ्य के कारण क्वेरी के रूप में करूंगा कि, Sql सर्वर के दृष्टिकोण से, मैंने प्रतिस्थापित कर दिया है हार्ड कोडित मानों के साथ पैरामीटर (मैं Sql सर्वर को अपनी क्वेरी भेजने से पहले कोड में इनपुट होगा)। क्या आप इसके आस-पास का रास्ता जानते हैं? क्या मेरे इन-लाइन एसक्यूएल स्टेटमेंट में वेरिएबल्स की घोषणा करने से क्वेरी ऑप्टिमाइज़र को मेरी कैश्ड क्वेरी प्लान खोजने में मदद मिलेगी?
जेम्स लेविस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.