2012-05-18 15 views
6

मुझे दो बार एक ही प्रश्न का उपयोग करने की आवश्यकता है, लेकिन थोड़ा अलग है जहां खंड। मैं सोच रहा था कि क्या यह एक ही संग्रहित प्रो को थोड़ा सा मूल्य के साथ कॉल करने में सक्षम होगा, और एक IF ... ELSE ... कथन है, जिस पर निर्णय लेने के लिए फ़ील्ड का निर्णय लेना है।संग्रहित प्रक्रियाओं में तर्क प्रवाह के लिए एसक्यूएल सर्वर निष्पादन योजना कैसे संकलित करता है?

या मुझे दो संग्रहित प्रोसेस बनाना चाहिए और मेरे ऐप में तर्क के आधार पर प्रत्येक को कॉल करना चाहिए?

मैं इसे और अधिक विस्तार से जानना चाहता हूं हालांकि सही ढंग से समझना है। इसके लिए निष्पादन योजना कैसे संकलित की जाती है? क्या प्रत्येक IF में प्रत्येक कोड ब्लॉक के लिए कोई है ... ELSE ...?

या इसे एक बड़ी निष्पादन योजना के रूप में संकलित किया गया है?

+0

क्या होगा 'अगर ... बाकी पर

अधिक जानकारी .. .' (या 'केस') में बिल्कुल शामिल है? कुछ मामलों में यह पैरामीटर में सशर्त अमूर्त करने के लिए संभव और अधिक कुशल है। आपके पास प्रति proc एक निष्पादन योजना है, इसलिए सशर्त तर्क के परिणामस्वरूप असमान प्रदर्शन हो सकता है। –

उत्तर

1

यह प्रक्रिया में पारित पैरामीटर के प्रारंभिक मूल्य का उपयोग करके संकलित किया जाता है। हालांकि कुछ कथन स्थगित संकलन के अधीन हो सकते हैं, इस मामले में वे अंततः संकलित होने पर पैरामीटर मानों के साथ संकलित किए जाएंगे।

आप इसे नीचे चलाने और वास्तविक निष्पादन योजनाओं को देखने से देख सकते हैं।

CREATE TABLE T 
    (
    C INT 
) 

INSERT INTO T 
SELECT 1 AS C 
UNION ALL 
SELECT TOP (1000) 2 
FROM master..spt_values 
UNION ALL 
SELECT TOP (1000) 3 
FROM master..spt_values 

GO 

CREATE PROC P @C INT 
AS 
    IF @C = 1 
     BEGIN 
      SELECT '1' 
      FROM T 
      WHERE C = @C 
     END 
    ELSE IF @C = 2 
     BEGIN 
      SELECT '2' 
      FROM T 
      WHERE C = @C 
     END 
    ELSE IF @C = 3 
     BEGIN 
      CREATE TABLE #T 
      (
       X INT 
      ) 

      INSERT INTO #T 
      VALUES  (1) 

      SELECT '3' 
      FROM T, 
       #T 
      WHERE C = @C 
     END 

GO 

EXEC P 1 

EXEC P 2 

EXEC P 3 

DROP PROC P 

DROP TABLE T 

2 मामले चल रहा है पंक्तियों की अनुमानित संख्या से T रूप 1 नहीं 1000 आ रहा क्योंकि इस कथन 1 की में पारित प्रारंभिक पैरामीटर मान के अनुसार संकलित किया गया था पता चलता है। केस चलाना 1000 की सटीक अनुमानित गणना देता है (अभी तक बनाया जाना चाहिए) अस्थायी तालिका का अर्थ है कि कथन एक स्थगित संकलन के अधीन था।

3

आपको कैश किए जाने वाले निष्पादन योजना के बारे में चिंतित होने का अधिकार है।

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

इसके पीछे कारण "पैरामीटर स्नीफिंग" कहा जाता है और यह शोध करने योग्य है।

एक आम प्रस्तावित समाधान (जिसे मैं सलाह नहीं देता) अपने स्पोक को कुछ छोटे लोगों में विभाजित करना है। यदि आप एक स्पोक के अंदर एक स्पोक कहते हैं कि आंतरिक स्पोक को निष्पादित करने के लिए अनुकूलित निष्पादन योजना मिल जाएगी।

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

एक पैरामीटर के अनुसार एक अलग जहां खंड के साथ एक क्वेरी बनाने के अपने प्रश्न पर वापस आने के लिए।मैं निम्नलिखित पैटर्न का प्रयोग करेंगे:

WHERE 
(@parameter1 is null or col1 = @parameter1 ) 
AND 
(@parameter2 is null or col2 = @parameter2 ) 
... 
OPTION (RECOMPILE) 

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

उल्टा यह है कि आप पठनीय और सुरुचिपूर्ण sprocs कोड कर सकते हैं और गलत पैर पर अनुकूलक सेट नहीं कर सकते हैं।

ध्यान रखने योग्य एक और विकल्प यह है कि आप स्पोक स्तर (निष्पादन स्तर के विपरीत) स्तर पर निष्पादन योजना कैशिंग अक्षम कर सकते हैं जो कम दानेदार है और, अधिक महत्वपूर्ण बात यह है कि स्थानीय चर के मूल्य को ध्यान में नहीं रखा जाएगा अनुकूलन करते समय। http://www.sommarskog.se/dyn-search-2005.html http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/

+0

कोई अपवॉट क्यों नहीं? एक वैध जवाब। –

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

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