क्वेरी है
SELECT SUM(Amount) AS SummaryTotal
FROM PDetail WITH(NOLOCK)
WHERE ClientID = @merchid
AND PostedDate BETWEEN @datebegin AND @dateend
तालिका में 103,129,000 पंक्तियाँ हैं।
फास्ट प्लान क्लाइंटआईड द्वारा डेट पर अवशिष्ट के साथ दिखता है लेकिन पुनः प्राप्त करने के लिए 96 लुकअप करने की आवश्यकता है Amount
। <ParameterList>
योजना में खंड इस प्रकार है।
<ParameterList>
<ColumnReference Column="@dateend"
ParameterRuntimeValue="'2013-02-01 23:59:00.000'" />
<ColumnReference Column="@datebegin"
ParameterRuntimeValue="'2013-01-01 00:00:00.000'" />
<ColumnReference Column="@merchid"
ParameterRuntimeValue="(78155)" />
</ParameterList>
धीमी योजना तिथि तक दिखती है और क्लाइंटआईड पर अवशिष्ट का मूल्यांकन करने और राशि प्राप्त करने के लिए लुकअप (अनुमानित 1 बनाम वास्तविक 7,388,383) है। <ParameterList>
अनुभाग है
<ParameterList>
<ColumnReference Column="@EndDate"
ParameterCompiledValue="'2013-02-01 23:59:00.000'"
ParameterRuntimeValue="'2013-02-01 23:59:00.000'" />
<ColumnReference Column="@BeginDate"
ParameterCompiledValue="'2013-01-01 00:00:00.000'"
ParameterRuntimeValue="'2013-01-01 00:00:00.000'" />
<ColumnReference Column="@ClientID"
ParameterCompiledValue="(78155)"
ParameterRuntimeValue="(78155)" />
</ParameterList>
इस दूसरे मामले में ParameterCompiledValue
है नहीं खाली। SQL सर्वर क्वेरी में उपयोग किए गए मानों को सफलतापूर्वक सूँघता है।
"SQL सर्वर 2005 प्रैक्टिकल समस्या निवारण" पुस्तक में स्थानीय चर का उपयोग करने के बारे में कहा गया है
हार पैरामीटर सूंघने के लिए स्थानीय चर का उपयोग करना एक बहुत ही आम चाल है, लेकिन OPTION (RECOMPILE)
और OPTION (OPTIMIZE FOR)
संकेत ... आम तौर पर और अधिक सुरुचिपूर्ण और थोड़ा कम जोखिम भरा समाधान कर रहे हैं
ध्यान दें
SQL सर्वर 2005 में, कथन स्तर संकलन संकलन क्वेरी के पहले निष्पादन से ठीक पहले तक संग्रहीत कार्यविधि में एक व्यक्तिगत कथन के संकलन के लिए अनुमति देता है। तब तक स्थानीय चर का मान ज्ञात हो जाएगा। सैद्धांतिक रूप से SQL सर्वर स्थानीय चर मानों को उसी तरह से सूँघ सकता है, जिस तरह से यह मापदंडों को सूँघता है। हालाँकि, क्योंकि SQL Server 7.0 और SQL Server 2000+ में सूँघने के पैरामीटर को पराजित करने के लिए स्थानीय चर का उपयोग करना आम था, SQL Server 2005 में स्थानीय चर को सूँघना सक्षम नहीं था। यह भविष्य में SQL सर्वर रिलीज़ में सक्षम हो सकता है, जो एक अच्छा है इस अध्याय में उल्लिखित अन्य विकल्पों में से एक का उपयोग करने का कारण यदि आपके पास कोई विकल्प है।
एक त्वरित परीक्षण से यह अंत व्यवहार ऊपर वर्णित वह 2008 और 2012 में एक ही है और चर आस्थगित संकलन के लिए सूंघा नहीं कर रहे हैं, लेकिन केवल जब एक स्पष्ट OPTION RECOMPILE
संकेत किया जाता है।
DECLARE @N INT = 0
CREATE TABLE #T ( I INT );
/*Reference to #T means this statement is subject to deferred compile*/
SELECT *
FROM master..spt_values
WHERE number = @N
AND EXISTS(SELECT COUNT(*) FROM #T)
SELECT *
FROM master..spt_values
WHERE number = @N
OPTION (RECOMPILE)
DROP TABLE #T
आस्थगित संकलन के बावजूद चर सूँघा नहीं है और अनुमानित पंक्ति गणना गलत है
इसलिए मुझे लगता है कि धीमी योजना क्वेरी के एक मानकीकृत संस्करण से संबंधित है।
यह सभी मापदंडों के लिए ParameterCompiledValue
समान है ParameterRuntimeValue
, इसलिए यह विशिष्ट पैरामीटर सूँघने के लिए नहीं है (जहाँ मूल्यों के एक सेट के लिए योजना को संकलित किया गया था, फिर मूल्यों के दूसरे सेट के लिए चलाया गया)।
समस्या यह है कि सही पैरामीटर मानों के लिए संकलित योजना अनुचित है।
आप यहाँ और यहाँ वर्णित तारीखों के साथ इस मुद्दे को मारने की संभावना है । 100 मिलियन पंक्तियों वाली तालिका के लिए आपको SQL सर्वर द्वारा स्वचालित रूप से आपके लिए आंकड़े अपडेट करने से पहले 20 मिलियन सम्मिलित करने (या अन्यथा संशोधित) करने की आवश्यकता होती है। ऐसा लगता है कि पिछली बार अपडेट की गई शून्य पंक्तियों को क्वेरी में दिनांक सीमा से मिलान किया गया था, लेकिन अब 7 मिलियन करते हैं।
आप अधिक लगातार आँकड़े अपडेट शेड्यूल कर सकते हैं, ट्रेस झंडे पर विचार 2389 - 90
कर सकते हैं या इसका उपयोग कर सकते हैं, OPTIMIZE FOR UKNOWN
इसलिए यह केवल datetime
कॉलम पर वर्तमान में भ्रामक आंकड़ों का उपयोग करने में सक्षम होने के बजाय अनुमानों पर वापस आता है ।
यह SQL सर्वर के अगले संस्करण (2012 के बाद) में आवश्यक नहीं हो सकता है। एक संबंधित कनेक्ट आइटम पेचीदा प्रतिक्रिया शामिल
Microsoft द्वारा 8/28/2012 को 1:35 PM पर पोस्ट किया गया है कि
हमने अगले प्रमुख रिलीज़ के लिए कार्डिनैलिटी अनुमान वृद्धि की है जो अनिवार्य रूप से इसे ठीक करता है। हमारे पूर्वावलोकन सामने आने के बाद विवरण के लिए बने रहें। एरिक
2014 के इस सुधार को बेंजामिन नेवरेज़ ने लेख के अंत में देखा है:
नए SQL सर्वर कार्डिनैलिटी एस्टीमेटर पर एक पहली नज़र ।
ऐसा प्रतीत होता है कि नया कार्डिनैलिटी अनुमानक वापस गिर जाएगा और 1 पंक्ति अनुमान देने के बजाय इस मामले में औसत घनत्व का उपयोग करेगा।
2014 कार्डिनैलिटी अनुमानक और आरोही प्रमुख समस्या के बारे में कुछ अतिरिक्त विवरण:
SQL सर्वर 2014 में नई कार्यक्षमता - भाग 2 - नई कार्डिनैलिटी अनुमान