बाहरी कार्यों को 'बाहरी खंड' के साथ एक दृश्य से बुलाए जाने पर, विंडो फ़ंक्शंस में भयानक निष्पादन योजना होती है


10

मेरे पास यह मुद्दा बहुत समय पहले था, मुझे एक वर्कअराउंड मिला जिसने मुझे अनुकूल बनाया और इसके बारे में भूल गया।

लेकिन अब एसओ पर यह सवाल है तो मैं इस समस्या को लाने के लिए तैयार हूं।

ऐसा दृश्य है जो बहुत ही सरल तरीके से कुछ तालिकाओं को जोड़ता है (ऑर्डर + ऑर्डर लाइनें)।

जब एक 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 प्राथमिक कुंजी है? स्तंभ और पैरामीटर के डेटाटाइप्स मेल खाते हैं?
gbn

order_numberएक प्राथमिक कुंजी नहीं है। यह int not nullदोनों तालिकाओं में इस पर गैर-अनुक्रमित सूचकांक के साथ है।
GSerg

5
SQL सर्वर 2005 में इस क्षेत्र में विधेय के साथ समस्याएँ थीं । मुझे लगा कि वे अब तय हो गए हैं। BTW अपने TSQL उदाहरण एक पैरामीटर नहीं एक चर का उपयोग करता है। क्या OPTION (RECOMPILE)मदद जोड़ना है?
मार्टिन स्मिथ

1
@GSerg - तो फिल्टर के साथ खराब योजना पर अंतिम रूप से फिल्टर में अनुमानित 5 मिलियन पंक्तियाँ और वास्तविक से मेल खाती अनुमानित 10 पंक्तियाँ हैं? यदि ऐसा है तो शायद यह है कि विधेय धक्का मुद्दा अभी भी पूरी तरह से तय नहीं है।
मार्टिन स्मिथ

जवाबों:


5

ऐसा प्रतीत होता है कि यह एक लंबे समय तक चलने वाला मुद्दा है जो एक या दूसरे रूप में फिर से तैयार होता है और अभी भी SQL सर्वर 2012 में मौजूद है।

इस पर चर्चा करने वाले कुछ पद हैं

SQL सर्वर के सभी वर्तमान संस्करण 2012 तक और जिनमें शामिल हैं, यदि option(recompile)उपयोग किया जाता है (यदि 2008+) को छोड़कर किसी पैरामीटर किए गए विधेय के लिए अनुक्रम प्रोजेक्ट के पिछले विभाजन समूह पर फ़िल्टर पुश करने में सक्षम नहीं हैं ।

recompileसंकेत के लिए एक विकल्प के लिए फिर से लिखना होगा एक पैरामीटर इनलाइन TVF का उपयोग करने के लिए @ a1996 के रूप में सुझाव दिया गया है)


बस SQL ​​सर्वर 2014 में भी मामला था
Guillaume86

3

मैं टेबल-मूल्यवान udf द्वारा दृश्य को बदलने का प्रयास करूँगा। इस तरह यह रिकॉर्ड्स को पहले फ़िल्टर करेगा, और फिर विंडो फ़ंक्शन को लागू करेगा। यह फ़ंक्शन तालिका पैरामीटर को स्वीकार कर सकता है ताकि आप order_numberइसमें कई पास कर सकें


अभी तक एक और समाधान, हाँ। मैं ऐसा नहीं कर सका, क्योंकि सभी ग्राहक एक टेबल-वैल्यू फ़ंक्शन का उपभोग करने में सक्षम नहीं थे।
GSerg

क्यों? मुझे 100% यकीन नहीं है, लेकिन मुझे लगता है कि आप सभी को क्वेरी को थोड़ा बदलना होगा जैसेSELECT * FROM my_funct(12345)
a1ex07

एक्सेल (यानी, एमएस क्वेरी द्वारा) का उपयोग करके अंतिम उपयोगकर्ताओं द्वारा क्वेरी की आवश्यकता होती है, और एमएस क्वेरी आपको ऐसा करने की अनुमति नहीं देगी, कम से कम 2003 तक के संस्करणों में
19

it will filter records first, and then apply window functionगलत है। निष्पादन के लिए कोई
नियतकालिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.