SQL सर्वर को क्वेरी स्थितियों को लिखित रूप में चलाने के लिए बाध्य करता है?


14

मैं SQL Server 2008 R2 का उपयोग कर रहा हूं और मेरे पास यह छद्म क्वेरी (SP) है:

select ...
from ...
WHERE    @LinkMode IS NULL
     AND (myColumn IN (...very long-running query...))
     ...
     ...

समस्या यह है कि क्वेरी को निष्पादित करने में बहुत लंबा समय लगता है - भले ही मैं एसपी के साथ निष्पादित करता हूं @LinkMode=2

जैसा कि आपने देखा, लंबे समय से चल रहे क्वेरी को केवल तभी निष्पादित किया जाना चाहिए यदि @LinkMode शून्य है, जो यहां नहीं है। मेरे मामले में @LinkMode = 2!

हालाँकि, अगर मैं इसे बदल देता हूँ:

 select ...
    from ...
    WHERE    1=2
         AND (myColumn IN (...very long time exeted query...))
     ...
     ...

सपा करता तेजी से चलाते हैं।

मैंने पहले सुना है कि कभी-कभी ऑप्टिमाइज़र मानदंडों के क्रम को अनुकूलित कर सकता है।

इसलिए मैं पूछता हूँ :

  • भले ही ऑप्टिमाइज़र एक अलग मार्ग चुनता है, अगर जाँच करने से ज्यादा तेज़ क्या हो सकता है =null? मेरा मतलब है, मुझे लगता है कि जाँच if a==nullहै बहुत तेजी से अन्य लंबी क्वेरी चलाने की तुलना में ...

  • मैं SQL सर्वर को क्वेरी चलाने के लिए कैसे बाध्य कर सकता हूं क्योंकि मैंने इसे (उसी क्रम) लिखा है?

जवाबों:


22

आप " कैच-ऑल क्वेरी " जाल में गिर रहे हैं , जिसे यहां गेल शॉ ने बहुत अच्छी तरह से समझाया है

समस्या को सारांशित करने के लिए: SQL सर्वर क्वेरी संकलन के महत्वपूर्ण ओवरहेड को संकलन के बाद एक क्वेरी योजना को कैशिंग द्वारा अनुकूलित करता है, और फिर बाद में संकलन से पहले मिलान क्वेरी योजना के लिए कैश की जाँच करता है। यहां होने वाला "मिलान" विशुद्ध रूप से पाठ्य है, इसलिए एक चर का वास्तविक मूल्य इस पर प्रभाव नहीं डालेगा।

यह समय का 99% अच्छा है , लेकिन कुछ मामलों में यह बुरा है । एक ऐसा मामला जहां यह बुरा है जब कोई व्यक्ति WHERE क्लॉज का निर्माण करने की कोशिश करता है, जैसे कि इसकी शॉर्ट-सर्कुलेटिंग IF स्टेटमेंट इन C, आदि। तो यह अच्छी तरह से काम नहीं करता है, क्योंकि SQL कंपाइलर को एक क्वेरी प्लान बनाना होता है, जो बिना परवाह किए काम करेगा। पैरामीटर मान वास्तव में क्या हैं, और इसका एकमात्र तरीका यह है कि इन "चतुर" तार्किक स्विचिंग-शर्तों को कहां से हैंडल किया जा सकता है। एक साधारण ब्रूट-फोर्स प्लान बनाने के लिए है, जो पूरे टेबल को स्कैन करता है, पंक्तियों को छानता है जैसा कि यह जाता है , किसी भी सूचकांक का लाभ उठाए बिना।

आश्चर्य की बात नहीं, यह उन्हें समान रूप से धीमा बनाता है, चाहे कोई भी पैरामीटर / चर मान हो।


8

SQL सर्वर को एक विशिष्ट क्रम में आपकी क्लॉज़ शर्तों को निष्पादित करने के लिए बाध्य करने का कोई गारंटी तरीका नहीं है। ऑप्टिमाइज़र हमेशा उन्हें उस क्रम में मूल्यांकन करेगा, जिसे वह फिट देखता है।

आप कुछ ऐसा कर सकते हैं:

IF @LinkMode IS NULL
BEGIN
    select ...
    from ...
    WHERE (myColumn IN (...very long time exeted query...))
         ...
         ...
END
ELSE
BEGIN
    select ...
    from ...
    WHERE ...
         ...
END

3

यदि यह एक विकल्प है, तो क्वेरी के उपयुक्त रूप को निष्पादित करने के लिए एक IF कथन का उपयोग करें। इसके अलावा, SQL में, आप db इंजन को बताते हैं कि क्या करना है, कैसे नहीं करना है - चीजों को शुरू से अंत तक निष्पादित नहीं किया जाता है। यह भविष्यवाणी करना कठिन हो सकता है कि यह वास्तव में क्या करेगा। आप शायद यह जानते हैं;)


2

डायनेमिक एसक्यूएल भी शायद काम करेगा, क्योंकि उस स्थिति में क्वेरी ऑप्टिमाइज़र को रन-टाइम पर वास्तविक मान प्राप्त करना चाहिए (मुझे गलत होने पर सही करें, मैं वास्तव में निश्चित नहीं हूं लेकिन समान स्थितियों के लिए इसका उपयोग करना याद रखता हूं) । लेकिन मैं इस एक में दूसरों के साथ हूं, जिसमें एक IF / ELSE क्लॉज आपको सबसे अच्छी सेवा देगा, क्योंकि यह सबसे सरल और सबसे आसान समाधान है जो वास्तव में आवश्यक है।

यदि आपने अभी तक इसका उपयोग नहीं किया है, तो भविष्य में संदर्भ के लिए, गतिशील एसक्यूएल के लिए एक कामकाजी उदाहरण के साथ एक भयानक बदसूरत साइट उदाहरण के लिए यहां पाई जा सकती है: http://sqlusa.com/bestpractices/dynamicsql/


1

मैं आईएफ / ईएलएसई निर्माण की सिफारिश करूंगा .. यदि किसी भी कारण से जो आपके लिए काम नहीं करता है, तो आप हमेशा दूरसंचार विकल्प का उपयोग करके विचार कर सकते हैं।


क्या आप इस बात पर विस्तार से बता सकते हैं कि "अगर / और निर्माण" जैसा दिख सकता है? : D
jcolebrand

मैं विकल्प (RECOMPILE के साथ) का उपयोग करने का सुझाव देने जा रहा था, क्योंकि इससे हर बार एक आदर्श योजना बनती थी - संकलन में देरी ओवरहेड जोड़ देगा, लेकिन मुझे संदेह है कि यह इस मामले में बेहतर है।
SqlRyan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.