आपकी प्रारंभिक क्वेरी का हिस्सा निम्नानुसार है।
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
मूल्य नहीं है।