आपकी प्रारंभिक क्वेरी का हिस्सा निम्नानुसार है।
FROM [dbo].[calendar] a
LEFT JOIN [dbo].[colleagueList] b
ON b.[Date] = a.d
WHERE DAY(a.[d]) = 1
AND a.[d] BETWEEN @dateStart AND COALESCE(@dateEnd,@dateStart)
योजना का वह भाग नीचे दिखाया गया है

आपकी संशोधित क्वेरी BETWEEN @dateStart AND ISNULL(@dateEnd,@dateStart)में इसी शामिल होने के लिए है

यह अंतर ऐसा प्रतीत होता है कि ISNULLआगे सरल हो जाता है और इसके परिणामस्वरूप आपको अधिक सटीक कार्डिनैलिटी के आँकड़े मिलते हैं जो अगली जॉइन में जाते हैं। यह एक इनलाइन टेबल वैल्यू फ़ंक्शन है और आप इसे शाब्दिक मूल्यों के साथ कह रहे हैं ताकि यह कुछ ऐसा कर सके।
a.[d] BETWEEN @dateStart AND ISNULL(@dateEnd,@dateStart)
a.[d] BETWEEN '2013-06-01' AND ISNULL(NULL,'2013-06-01')
a.[d] BETWEEN '2013-06-01' AND '2013-06-01'
a.[d] = '2013-06-01'
और जैसा कि एक सम्मिलित है विधेय b.[Date] = a.dको सम्मिलित करें एक समता को सम्मिलित दर्शाता है b.[Date] = '2013-06-01'। परिणामस्वरूप 28,393पंक्तियों का कार्डिनैलिटी अनुमान बहुत सटीक होने की संभावना है।
के लिए CASE/ COALESCEसंस्करण जब @dateStartऔर @dateEndएक ही मूल्य तो यह सरल ही समानता अभिव्यक्ति के लिए ठीक हैं और एक ही योजना देता है, लेकिन जब @dateStart = '2013-06-01'और @dateEnd IS NULLयह केवल जहाँ तक चला जाता है
a.[d]>='2013-06-01' AND a.[Date]<=CASE WHEN (1) THEN '2013-06-01' ELSE NULL END
यह भी एक निहित भविष्यवाणी के रूप में लागू होता है ColleagueList। इस बार पंक्तियों की अनुमानित संख्या 79.8पंक्तियाँ हैं।
अगला साथ है
LEFT JOIN colleagueTime
ON colleagueTime.TC_DATE = colleagueList.Date
AND colleagueTime.ASSOC_ID = CAST(colleagueList.ID AS VARCHAR(10))
colleagueTimeएक 3,249,590पंक्ति तालिका है जो (फिर से) स्पष्ट रूप से कोई उपयोगी अनुक्रमित के साथ एक ढेर है।
अनुमानों में यह विसंगति इस्तेमाल की गई पसंद को प्रभावित करती है। ISNULLयोजना एक हैश में शामिल होने कि सिर्फ एक बार तालिका को स्कैन करता है चुनता है। COALESCEयोजना एक नेस्टेड छोरों में शामिल होने के लिए चुनता है और अनुमान है कि यह अभी भी सिर्फ एक बार तालिका स्कैन और परिणाम स्पूल और 78 बार यह पुनः चलाने के लिए सक्षम होने के लिए की आवश्यकता होगी। यानी यह अनुमान है कि सहसंबद्ध पैरामीटर नहीं बदलेगा।
इस तथ्य से कि नेस्टेड छोरों की योजना दो घंटे बाद भी चल रही थी, इसके खिलाफ एकल स्कैन की धारणा colleagueTimeअत्यधिक गलत होने की संभावना है।
दो जोड़ों के बीच पंक्तियों की अनुमानित संख्या इतनी कम क्यों है, इसके बारे में मुझे यकीन नहीं है कि हम तालिकाओं पर आंकड़े देख सकते हैं। एक ही तरीका है कि मैं अनुमानित पंक्ति गणना को तिरछा करने में कामयाब रहा कि मेरे परीक्षण में बहुत अधिक NULLपंक्तियों का भार शामिल था (इससे अनुमानित पंक्ति संख्या कम हो गई, जबकि पंक्तियों की वास्तविक संख्या समान बनी रही)।
COALESCEमेरे परीक्षण डेटा के साथ योजना में अनुमानित पंक्ति गणना के क्रम में थी
number of rows matching >= condition * 30% * (proportion of rows in the table not null)
या SQL में
SELECT 1E0 * COUNT([Date]) / COUNT(*) * ( COUNT(CASE
WHEN [Date] >= '2013-06-01' THEN 1
END) * 0.30 )
FROM [dbo].[colleagueList]
लेकिन यह आपकी टिप्पणी के अनुसार नहीं है कि कॉलम में कोई NULLमूल्य नहीं है।