2016-01-20 8 views
5

हाल ही में मेरे पास एक प्रदर्शन ट्यूनिंग अनुभव था और मैं इसे यहां साझा करना चाहता हूं और यह समझने की कोशिश कर रहा हूं कि यह सुधार क्यों हुआ।क्यों एक चर के लिए एक क्वेरी की गिनती असाइन करना सीधे इसे जांचने से बेहतर प्रदर्शन किया?

मेरी एक प्रो में से, मैं कुछ अन्य रिकॉर्ड के अस्तित्व के आधार पर एक डेटा सेट वापस करना चाहता था।

मेरे प्रश्न:

IF (SELECT COUNT(1) FROM ...) > 0 
    SELECT … 

इस क्वेरी के आसपास 5 सेकंड ले रहा था।

मैंने एक बदलाव किया और IF कथन को एक चर के लिए आउटपुट सौंपा, फिर इसे जांचें।

DECLARE @cnt INT = 0 
SELECT @cnt = COUNT(1) FROM … 

IF @cnt > 0 
    SELECT … 

इसे चलाने के लिए 1 सेकंड से भी कम समय लगता है।

इसके अलावा मैंने IF EXISTS भी कोशिश की लेकिन सुधार से पहले एक ही परिणाम मिला (5 सेकंड)।

मैं जानना चाहता हूं कि संकलक इतना अलग क्यों व्यवहार करता है और यदि उसके लिए कोई विशेष उत्तर है।

धन्यवाद

+0

पॉल व्हाइट ने dba.se पर एक बहुत अच्छा जवाब दिया: [अगर EXSTST एम्बेडेड चुनिंदा कथन से अधिक समय ले रहा है] (http://dba.stackexchange.com/questions/126235/if-exists-taking-longer-than- एम्बेडेड-चयन-कथन) इस प्रश्न को डुप्लिकेट के रूप में चिह्नित किया जाना चाहिए, लेकिन उत्तर SO पर नहीं है। –

+0

धन्यवाद @VladimirBaranov उस सवाल को इंगित करने के लिए। बहुत मददगार था लेकिन मैं जानना चाहता हूं कि इसे एक चर को असाइन करने और इसे सीधे कॉल करने के बीच एक अंतर क्यों है। यहां मेरा इरादा 'IF EXISTS' का उपयोग नहीं कर रहा है। – sqluser

+0

सबसे अधिक संभावना अनुकूलक 'IF (चुनें COUNT (1) से ...)> 0' 'अगर EXISTS ...' में परिवर्तित हो जाता है। मैंने सोचा कि पॉल व्हाइट द्वारा जवाब में इसका उल्लेख किया गया था, लेकिन अब मैं इसे वहां नहीं देख रहा हूं। मैंने इसे कहीं और देखा होगा। निष्पादन योजना की जांच करें। यदि अनुकूलक वास्तव में 'IF COUNT> 0' को 'IF EXISTS' में परिवर्तित करता है, तो' EXISTS' के साथ एक पंक्ति लक्ष्य का परिचय आपको प्राप्त होने वाली गैर-इष्टतम निष्पादन योजना की व्याख्या करेगा। –

उत्तर

3

यहां दो भाग हैं।

1) एसक्यूएल सर्वर अनुकूलक

IF (SELECT COUNT(1) FROM ...) > 0 
    SELECT … 

धर्मान्तरित में

IF EXISTS(SELECT 1 FROM ...) 
    SELECT … 

मैंने देखा है कि इस एंड्रयू केली Exists Vs. Count(*) - The battle never ends द्वारा पोस्ट करने के लिए अपने टिप्पणी में एडम Machanic द्वारा बताया गया:

यह ध्यान रखना दिलचस्प है कि SQL Server 2005 में यदि कोई अनुक्रमणिका है एक खोज की अनुमति देने के लिए उपलब्ध, COUNT (*)> 0 परीक्षण अनुकूलित किया जाएगा और EXISTS के समान व्यवहार करेगा।

एडम ने वहां एक डेमो प्रदान किया।


2) कभी कभी EXISTSCOUNT से भी बदतर है:

IF EXISTS taking longer than embedded select statement

Check existence with EXISTS outperform COUNT! … Not?

पॉल व्हाइट wrote के रूप में:

EXISTS प्रस्तुत किया जाने का उपयोग करना एक पंक्ति लक्ष्य, जहां ऑप्टिमाइज़र पहली पंक्ति को तुरंत ढूंढने के उद्देश्य से निष्पादन योजना का उत्पादन करता है। ऐसा करने में, यह मानता है कि डेटा समान रूप से वितरित किया गया है। उदाहरण के लिए, यदि आंकड़े बताते हैं कि 100,000 पंक्तियों में 100 अपेक्षित मिलान हैं, तो मान लेंगे कि इसे पहले मैच खोजने के लिए केवल 1,000 पंक्तियां पढ़नी होंगी।

यह धारणा दोषपूर्ण साबित होने पर अपेक्षित निष्पादन समय से अधिक समय में परिणाम देगा। उदाहरण के लिए, यदि SQL सर्वर एक एक्सेस विधि (उदा। अनॉर्डर्ड स्कैन) चुनता है जो खोज में बहुत देर से पहले मिलान मूल्य का पता लगाने के लिए होता है, तो इसका परिणाम लगभग पूर्ण स्कैन हो सकता है। दूसरी ओर, यदि पर मिलान करने वाली पंक्ति पहली कुछ पंक्तियों में पाई जाती है, तो प्रदर्शन बहुत अच्छा होगा। यह पंक्ति लक्ष्यों के साथ मौलिक जोखिम है - असंगत प्रदर्शन।


यदि आपका डेटा वितरण विषम है या यदि आप उम्मीद करते हैं कि अधिकांश मामलों में COUNT शून्य (यानी तुम वैसे भी पूरे तालिका स्कैन करने के लिए इस सवाल का जवाब पाने के लिए है), तो आप की कोशिश करनी चाहिए होगा एक पंक्ति लक्ष्य के बिना योजना प्राप्त करें (यानी EXISTS के बिना)।

एक स्पष्ट तरीका जैसा कि आप पहले ही पाए गए हैं COUNT के परिणाम को एक चर में सहेजना है।

+0

इन सभी उपयोगी जानकारी के लिए धन्यवाद। मैं थोड़ी देर के लिए कुछ और ध्यान पाने के लिए इसे छोड़ देता हूं। – sqluser

संबंधित मुद्दे