2012-06-20 12 views
8

मान कोडिंग हार्ड कोडिंग करता है मेरे पास एक संग्रहित प्रक्रिया है जो बहुत कुछ करती है। जब मैं एक चर घोषित करता हूं, तो अपना मान निर्धारित करता हूं और फिर उस खंड में इसका उपयोग करता हूं जहां बयान में एक घंटे से अधिक समय लगता है। जब मैं हार्ड कोड को चर कोड करता हूं जहां यह खंड एक सेकंड से भी कम समय में चलता है।पैरामीटर प्रदर्शन नहीं करता है साथ ही

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

 
/************* Begin of Stored Procedure ***************/ 
CREATE PROCEDURE GetFruit 
    @ColorId bigint, 
    @SeasionId bigint 
WITH RECOMPILE 
AS 
BEGIN 

SELECT 
    A.Name 
FROM 
    [Apple_View] A /* This is the view down below */ 
    INNER JOIN [Fruit] F 
     ON (F.ColorId = @ColorId 
      AND A.FruitId = F.FruitId)   
WHERE 
    (A.ColorId = @ColorId 
    AND 
    A.SeasonId = @SeasonId) 

END 
/************* End of Stored Procedure ***************/ 

/************* Begin of View ***************/ 
WITH Fruits (FruitId, ColorId, SeasonId) AS 
(
    -- Anchor member 
    SELECT 
     F.FruitId 
     ,F.ColorId 
     ,F.SeasonId 
    FROM 
     (( 
      SELECT DISTINCT 
       EF.FruitId 
       ,EF.ColorId 
       ,EF.SeasonId 
       ,EF.ParentFruitId 
      FROM 
       ExoticFruit EF 
       INNER JOIN Fruit FR 
        ON FR.FruitId = EF.FruitId 
     UNION 
      SELECT DISTINCT 
       SF.FruitId 
       ,SF.ColorId 
       ,SF.SeasonId 
       ,SF.ParentFruitId    
      FROM 
       StinkyFruit SF 
       INNER JOIN Fruit FR 
        ON FR.FruitId = SF.FruitId 
     UNION 
      SELECT DISTINCT 
       CF.FruitId 
       ,CF.ColorId 
       ,CF.SeasonId 
       ,CF.ParentFruitId 
      FROM 
       CrazyFruit CF 
       INNER JOIN Fruit FR 
        ON FR.FruitId = CF.FruitId 

      )) f 

    UNION ALL 

    -- Recursive Parent Fruit 
    SELECT 
     FS.FruitId 
     ,FS.ColorId 
     ,FS.SeasonId 
     ,FS.ParentFruitId 
    FROM 
     Fruits FS 
     INNER JOIN MasterFruit MF 
      ON MF.[ParentFruitId] = fs.[FruitId] 
) 

SELECT DISTINCT 
    FS.FruitId 
    ,FS.ColorId 
    ,FS.SeasonId 
    FROM 
     Fruits FS 

/************* End of View ***************/ 


/* To Execute */ 
EXEC GetFruit 1,3 

अगर मैं सेट मूल्यों यह एक घंटे से अधिक समय लगता है और यहाँ का उपयोग कर संग्रहित प्रक्रिया चलाने के लिये कार्य योजना लागू है।

WHERE(A.ColorId = 1 AND A.SeasonId = 3) 

hard coded where clause: With Variables

अगर मैं संग्रहित प्रक्रिया घोषित करने और सेट मूल्यों को दूर करने और सिर्फ निम्न कथन यह एक दूसरे से कम में चलता है और यहाँ कहाँ खंड सेट चलाने के लिये कार्य योजना लागू है

ध्यान दें कि हार्ड कोडित वेरिएबल्स इंडेक्सिंग का उपयोग कैसे करते हैं जबकि पहले हैश सेट का उपयोग करता है। ऐसा क्यों है? जहां घोषित चर से अलग काम कर रहे हैं, वहां कठोर कोडित मूल्य क्यों हैं?

------- यह है कि क्या अंत में

मैं संग्रहीत प्रक्रिया बदल sp_executesql उपयोग करने के लिए @ user1166147 ------ की मदद से किया जाता है।

 
CREATE PROCEDURE GetFruit 
    @ColorId bigint, 
    @SeasionId bigint 
WITH RECOMPILE 
AS 
BEGIN 

DECLARE @SelectString nvarchar(max) 

SET @SelectString = N'SELECT 
    A.Name 
FROM 
    [Apple_View] A /* This is the view down below */ 
    INNER JOIN [Fruit] F 
     ON (F.ColorId = @ColorId 
      AND A.FruitId = F.FruitId)   
WHERE 
    (A.ColorId = ' + CONVERT(NVARCHAR(MAX), @ColorId) + ' 
    AND 
    A.SeasonId = ' + CONVERT(NVARCHAR(MAX), @SeasonId) + ')' 

EXEC sp_executesql @SelectString 

END 
+0

आप सुनिश्चित करें कि आपके पैरामीटर डेटा प्रकार स्तंभ डेटा प्रकार मिलान करने के लिए जांच की है? – HackedByChinese

+2

ये चर नहीं हैं पैरामीटर। एसक्यूएल सर्वर परिवर्तनीय स्नीफिंग नहीं करता है इसलिए चयनशीलता अनुमान अनुमान लगाए जाएंगे। यदि आप 'विकल्प (रिकॉम्प्ली)' जोड़ते हैं तो क्या होगा? –

+1

विकल्प विकल्प recompile। वहाँ कुछ पैरामीटर स्नीफिंग कहा जाता है जिसमें SQL सर्वर इनपुट मान – praveen

उत्तर

2

Damien_The_Unbeliever

से संपादन सारांश एक अनुरोध के अनुसार लक्ष्य SQL करने से पहले योजना बनाई गई है, आम तौर पर पैरामीटर सूंघने करता चर मूल्य के बारे में सबसे अच्छा/सबसे जानकारी पाने के लिए है। इस मामले में पैरामीटर स्नीफिंग 'अक्षम' होने का एक कारण हो सकता है। वास्तविक कोड का बेहतर प्रतिनिधित्व देखने के बिना हम वास्तव में नहीं कह सकते कि समाधान क्या है या समस्या क्यों मौजूद है। प्रभावित क्षेत्रों को वास्तविक मूल्यों का उपयोग करके योजनाएं उत्पन्न करने के लिए मजबूर करने के लिए नीचे दी गई चीज़ों को आज़माएं।

* अधिक विवरण *

के साथ लंबे संस्करण इस अपने वास्तविक संग्रहीत proc है? क्या आपके पास अपने पैरामीटर के लिए डिफ़ॉल्ट मान हैं? यदि ऐसा है, तो वो क्या हैं?

पैरामीटर स्नीफिंग मदद कर सकता है - लेकिन योजना को अच्छी तरह से बनाने के लिए इसमें सामान्य पैरामीटर मान होना चाहिए, और यदि नहीं, तो वास्तव में गैर विशिष्ट पैरामीटर मान के आधार पर खराब योजना बनाने में मदद नहीं करेगा। इसलिए यदि किसी चर के पास शून्य या डिफ़ॉल्ट मान का डिफ़ॉल्ट मान होता है जो कि पहली बार चलाया जाता है और यह योजना संकलित की जाती है - यह एक खराब योजना बनाता है।

अगर किसी और ने यह स्पोक लिखा है - तो वे जानबूझकर 'अक्षम' पैरामीटर को किसी कारण के लिए स्थानीय चर के साथ स्नीफिंग कर सकते हैं। व्यापार नियमों को इन परिवर्तनीय संरचनाओं की आवश्यकता हो सकती है।

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

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

वास्तविक कोड का बेहतर प्रतिनिधित्व देखने के बिना, यह देखना मुश्किल है कि समस्या क्या है। उम्मीद है कि यह जानकारी मदद करेगी -

+0

जबकि आपके संपादन मूड में - फिलहाल, यह सिर्फ टेक्स्ट की दीवार है। शायद इसे पैराग्राफ में तोड़ने का प्रयास करें? –

+0

यह वास्तविक संग्रहीत प्रक्रिया नहीं है। यह 9 5% सटीक है, इसकी तालिका प्रणाली और कॉलम को वित्तीय प्रणाली के बाद निजी रखने के लिए कॉलम नामों में बदलाव आया है। * मुझे पता है कि यह बेकार है और इसे कठिन बनाता है। मैं क्षमा चाहता हूं कि मुझे ऐसा करना पड़े, लेकिन मैंने इसे कम से कम बनाने के लिए अपना सर्वश्रेष्ठ प्रयास किया क्योंकि मैं कम से कम – Mark

+0

के साथ कर सकता था, मैं इसे 'sp_executesql' का उपयोग करके एक सेकंड से भी कम समय में करने में सक्षम था। भविष्य में उपयोगकर्ताओं के लिए मैं अपने प्रश्न में समाधान रखूंगा। – Mark

0

आप इसे सामान्य मूल्यों के आधार पर अपनी क्वेरी को अनुकूलित करने के लिए मजबूर कर सकते हैं जिसे आप बेहतर जानते हैं। आपकी मूल क्वेरी के लिए निम्नलिखित जोड़ें:

OPTION (OPTIMIZE FOR(@ColorId = 1, @SeasionId = 3)) 

यह गतिशील एसक्यूएल बिना समान प्रभाव होगा। आप विशिष्ट मूल्यों पता नहीं है हैं, तो आप अनुकूलक उन्हें सूँघने बना सकते हैं:

OPTION (OPTIMIZE FOR UNKNOWN) 

फिर से, कोई गतिशील एसक्यूएल

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