मेरे पास यह मुद्दा बहुत समय पहले था, मुझे एक वर्कअराउंड मिला जिसने मुझे अनुकूल बनाया और इसके बारे में भूल गया।
लेकिन अब एसओ पर यह सवाल है तो मैं इस समस्या को लाने के लिए तैयार हूं।
ऐसा दृश्य है जो बहुत ही सरल तरीके से कुछ तालिकाओं को जोड़ता है (ऑर्डर + ऑर्डर लाइनें)।
जब एक where
खंड के बिना समझा जाता है , तो दृश्य कई मिलियन लाइनें लौटाता है।
हालाँकि, कोई भी इसे कभी भी कॉल नहीं करता है। सामान्य प्रश्न है
select * from that_nasty_view where order_number = 123456;
यह 5 मी में से लगभग 10 रिकॉर्ड लौटाता है।
एक महत्वपूर्ण बात: दृश्य में एक विंडो फ़ंक्शन होता है rank()
, जिसे उस क्षेत्र द्वारा बिल्कुल विभाजित किया जाता है, जिसके उपयोग से दृश्य हमेशा क्वियर होता है:
rank() over (partition by order_number order by detail_line_number)
अब, यदि यह दृश्य क्वेरी स्ट्रिंग में शाब्दिक मापदंडों के साथ क्वेरी किया गया है, जैसा कि ऊपर दिखाया गया है, तो यह पंक्तियों को तुरंत लौटाता है। निष्पादन योजना ठीक है:
- सूचकांक दोनों तालिकाओं पर
order_number
(10 पंक्तियों की वापसी) का उपयोग करके तलाश करता है । - लौटे छोटे परिणाम पर खिड़कियों की गणना।
- का चयन करना।
हालांकि, जब दृश्य को पैरामीट्रिक तरीके से बुलाया जाता है, तो चीजें खराब हो जाती हैं:
Index scan
सूचकांकों की अनदेखी करने वाली सभी तालिकाओं पर। 5 मी पंक्तियाँ लौटाता है।- विशाल शामिल हुए।
- सभी के ऊपर खिड़कियों की गणना
partition
(लगभग 500k विंडोज़)। Filter
5 मीटर से 10 पंक्तियों को लेने के लिए।- चुनते हैं
यह सभी मामलों में होता है जब पैरामीटर शामिल होते हैं। यह SSMS हो सकता है:
declare @order_number int = 123456;
select * from that_nasty_view where order_number = @order_number;
यह ODBC क्लाइंट हो सकता है, जैसे Excel:
select * from that_nasty_view where order_number = ?
या यह कोई अन्य ग्राहक हो सकता है जो मापदंडों का उपयोग करता है और न कि एसक्यूएल संघटन।
यदि विंडो फ़ंक्शन को दृश्य से हटा दिया जाता है, तो यह पूरी तरह से जल्दी से चलता है, भले ही यह पैरामीटर के साथ क्वेरेड हो या नहीं।
मेरा काम यह था कि आपत्तिजनक कार्य को हटा दें और बाद के चरण में इसे पुन: लागू करें।
लेकिन, क्या देता है? क्या यह वास्तव में एक बग है जिसमें SQL सर्वर 2008 विंडो फ़ंक्शन को कैसे संभालता है?
order_number
एक प्राथमिक कुंजी नहीं है। यह int not null
दोनों तालिकाओं में इस पर गैर-अनुक्रमित सूचकांक के साथ है।
OPTION (RECOMPILE)
मदद जोड़ना है?