SQL सर्वर क्वेरी को निष्पादित करते समय कुछ पंक्तियों को वापस क्यों करता है, और कभी-कभी नहीं?


33

ऐसे प्रश्न हैं जहां हम "निष्पादित" करते हैं, यह कुछ पंक्तियों को दिखाता है और यह बढ़ता रहता है, लेकिन क्वेरी अभी खत्म नहीं हुई है। फिर भी कभी-कभी, यह क्वेरी के अंत तक इंतजार करता है।

क्यों होता है ऐसा? क्या इसे नियंत्रित करने का कोई तरीका है?

जवाबों:


43

जवाब, हमेशा की तरह (ठीक है, ज्यादातर समय), निष्पादन योजना में निहित है।

कुछ ऑपरेटर हैं जिन्हें उन पंक्तियों को संसाधित करने से पहले उन तक पहुंचने के लिए सभी पंक्तियों की आवश्यकता होती है और उदाहरण के लिए, उन्हें नीचे की ओर से गुजरना होता है:

  • हैश ज्वाइन (हैश टेबल बनाने पर)
  • हैश मैच
  • सॉर्ट (हश फ्लो डिस्टिक्ट को छोड़कर)

उन्हें या तो ब्लॉकिंग कहा जाता है, या इसके कारण ऑपरेटर बंद हो जाते हैं, और वे अक्सर चुने जाते हैं, जब ऑप्टिमाइज़र को लगता है कि आपके डेटा को खोजने के लिए उसे बहुत सारे डेटा को संसाधित करना होगा।

ऐसे अन्य ऑपरेटर हैं जो स्ट्रीमिंग को शुरू करने में सक्षम हैं, या किसी भी मिली हुई पंक्तियों को तुरंत पास कर रहे हैं

  • स्थिर फंदा
  • सूचकांक ने मर्ज जॉइन का समर्थन किया
  • स्ट्रीम एग्रीगेट्स

जब प्रश्न तुरंत डेटा लौटना शुरू करते हैं, लेकिन तुरंत समाप्त नहीं होते हैं, तो यह आमतौर पर एक संकेत है कि ऑप्टिमाइज़र ने ऑपरेटर्स का उपयोग करके जल्दी से कुछ पंक्तियों का पता लगाने और वापस करने की योजना को चुना जिसमें स्टार्ट अप की लागत कम है।

ऐसा आपके द्वारा या फिर ऑप्टिमाइज़र द्वारा शुरू किए गए पंक्ति लक्ष्यों के कारण हो सकता है।

यह भी हो सकता है कि अगर किसी कारण से किसी खराब योजना को चुना जाता है (एसएआरजीबिलिटी की कमी, पैरामीटर सूँघना, अपर्याप्त आंकड़े, आदि), लेकिन यह पता लगाने के लिए अधिक खुदाई होती है।

अधिक जानकारी के लिए, रोब फ़ार्ले के ब्लॉग की जाँच यहाँ

और पॉल व्हाइट की श्रृंखला पंक्ति लक्ष्यों पर यहाँ , यहाँ , यहाँ और यहाँ

यह भी ध्यान दिया जाना चाहिए कि, यदि आप SSMS के बारे में बात कर रहे हैं, तो पंक्तियाँ केवल एक बार दिखाई देती हैं, जब पूरा बफर भर जाता है, केवल विली-निली नहीं।


14

यदि मैं समझता हूं कि आप क्या देख रहे हैं, तो यह कैसे प्रबंधन स्टूडियो पंक्तियों को प्रस्तुत करता है , और SQL सर्वर पंक्तियों को कैसे लौटाता है, इसके साथ बहुत कम है । वास्तव में अक्सर जब आप SSMS को बड़े परिणाम दे रहे होते हैं और उन्हें ग्रिड में प्रस्तुत करने का प्रयास करते हैं, तो SSMS नहीं रख सकते हैं और SQL सर्वर एप्लिकेशन को अधिक पंक्तियों को संसाधित करने की प्रतीक्षा कर रहा है। इस स्थिति में आप SQL सर्वर को ASYNC_NETWORK_IOप्रतीक्षा करते हुए देखेंगे ।

परिणाम से ग्रिड तक पाठ के बजाय परिणाम का उपयोग करके आप इसे कुछ हद तक नियंत्रित कर सकते हैं, क्योंकि SSMS तेजी से पाठ आकर्षित कर सकता है क्योंकि यह ग्रिड आकर्षित कर सकता है, लेकिन आपको यह पता चलेगा कि यह कॉलम की संख्या और शामिल डेटा प्रकारों के आधार पर पठनीयता को प्रभावित कर सकता है। जब एसएसएमएस वास्तव में उस फलक पर परिणाम लिखने का फैसला करता है, तो दोनों प्रभावित होते हैं, जो इस बात पर निर्भर करता है कि आउटपुट बफर कितना पूर्ण है।

जब आपके पास कई कथन हों, और आप बफर को संदेश फलक में आउटपुट परिणाम प्रस्तुत करने के लिए बाध्य करना चाहते हैं, तो आप कथनों के बीच में थोड़ा प्रिंटिंग ट्रिक का उपयोग कर सकते हैं:

RAISERROR('', 0, 1) WITH NOWAIT;

लेकिन यह तब मदद नहीं करेगा जब आप SSMS को अधिक तेज़ी से पंक्तियों को प्रस्तुत करने की कोशिश कर रहे हों, जब सभी आउटपुट एक स्टेटमेंट से आ रहे हों।

अधिक सीधे, आप इसे SSMS में कितने परिणाम दे रहे हैं, इसे सीमित करके इसे नियंत्रित कर सकते हैं। मैं अक्सर लोगों को शिकायत करता हूं कि ग्रिड को एक लाख पंक्तियों को वापस करने में कितना समय लगता है। पृथ्वी पर कोई भी SSMS ग्रिड में एक लाख पंक्तियों के साथ क्या करने जा रहा है, मुझे नहीं पता।

कुछ हैक हैं OPTION (FAST 100), जो उन पहले 100 पंक्तियों (या कोई 100 पंक्तियों को प्राप्त करने के लिए अनुकूलित करेंगे यदि कोई बाहरी नहीं है ORDER BY), लेकिन यह शेष पंक्तियों के लिए बहुत धीमी पुनर्प्राप्ति की कीमत पर आ सकता है और एक योजना जो अधिक है समग्र रूप से अक्षम है, इसलिए वास्तव में एक विकल्प IMHO नहीं है।


1

आपका सवाल एसक्यूएल सेवर प्रति के बारे में नहीं है लेकिन:

  • एस क्यू एल सर्वर
  • नेटवर्क
  • ग्राहक आवेदन के रूप में एसएसएमएस

क्या इसे नियंत्रित करने का कोई तरीका है?

संक्षिप्त उत्तर :

  1. प्रयास करें sqlcmdबजाय ssmsया sqlcmdकी -Modessms
  2. अपने कनेक्शन और सत्र सेटिंग्स की जाँच करें

लंबे उत्तर :

बेशक! लेकिन एक नहीं - प्रोब

  1. Ssms में sqlcmdया के साथ अपनी क्वेरी निष्पादित करें sqlcmd
  2. यदि आप नेटवर्क की भूमिका को बाहर करना चाहते हैं - साझा मेमोरी कनेक्शन के साथ सर्वर पर अपनी क्वेरी चलाएं।
  3. यदि क्वेरी प्रदर्शन साझा मेमोरी कनेक्शन के साथ भी असंतोषजनक है - अपनी निष्पादन योजनाओं का विश्लेषण करें। यदि क्वेरी नेटवर्क के माध्यम से खराब करता है - मदद के लिए अपने नेटवर्क नेटवर्क व्यवस्थापक को कॉल करें। यदि आपकी क्वेरी केवल SSMS में खराब है - आगे पढ़ें।
  4. अब हमें यकीन है कि समस्याएँ ग्राहक की ओर हैं (इस मामले में ssms)। SSMS में कनेक्शन और सत्र सेटिंग्स को देखें। विश्वास मत करो ssms इंटरफ़ेस और SQL Profiler के साथ जाँच करें: अपने कनेक्शन को खोजें spidऔर आपको सत्र सेटिंग्स की पूरी सूची मिलती है। sqlcmdसत्र की सेटिंग्स के साथ तुलना करें । यदि कुछ भी क्लिक नहीं करता है - प्रोफाइलर से सभी सत्र सेटिंग्स को अपनी क्वेरी स्क्रिप्ट में कॉपी करें, sqlcmd-mode निष्पादित करें और धीरे-धीरे सेटिंग को स्विच करते हुए आप अपने अपराधी को पाएंगे।

सौभाग्य!


-2

Sp_BlitzErik के उत्तर में जोड़ने के लिए, NOT IN ()उप चयन के साथ उदाहरण का उपयोग करें। यह निर्धारित करने के लिए कि कोई आइटम नेस्टेड क्वेरी के परिणाम में है, यह (आम तौर पर) पूरे परिणाम को पुनः प्राप्त करने के लिए आवश्यक है।

इस तरह के प्रश्नों के प्रदर्शन को बेहतर बनाने के लिए एक आसान तरीका यह है कि उन्हें फिर से लिखना एक LEFT OUTER JOINऐसी स्थिति है जहाँ RIGHTपक्ष के लिए स्थिति अशक्त है (आप इसे चारों ओर फ्लिप कर सकते हैं, निश्चित रूप से लेकिन कौन उपयोग करता है RIGHT OUTER JOINS?)। यह परिणामों को तुरंत वापस लौटने के लिए शुरू करने की अनुमति देता है।


मुझे ऐसा नहीं लगता। यदि तुलना किए गए कॉलम अशक्त नहीं हैं, तो परिणाम समान और योजनाएं होनी चाहिए - आमतौर पर - समान, एक एंटिजन की 3 संस्करणों के लिए (NOT IN, NOT EXISTS, LEFT JOIN / IS NULL)। पूरे परिणाम को प्राप्त करना आवश्यक नहीं है।
ypercube y

यदि subselect एक वास्तव में जटिल है, तो उत्पादित क्वेरी को NOT, हालत, WHERE t.x IN (<complex SELECT subquery>)बराबर LEFT JOIN, की जाँच करने से पहले पूरे subselect का मूल्यांकन करने की आवश्यकता होती है LEFT JOIN (<complex SELECT subquery>) AS r ON r.x = t.x .... WHERE r.x IS NULL, तो subquery wil lhave का मूल्यांकन किया जाना चाहिए, (इसलिए जटिल जटिल योजना नहीं है। संस्करण)।
ypercube y

@ ypercube y यह मेरे लिए अतीत में काम कर चुका है। मैंने देखा है कि सब-सेकंड में लौटने के लिए प्रश्नों को मिनटों से जाना जाता है।
जिमीजैम

@ ypercube y मैंने ओरेकल में एक सरल उदाहरण दिया (क्षमा करें, इस समय मेरे पास SQLServer तक पहुंच नहीं है) और उनके पास निश्चित रूप से अलग-अलग व्याख्या योजनाएं थीं। शायद वे सार्थक मतभेद नहीं थे, लेकिन वे बहुत अलग दिखते हैं।
जिमीजैम

@ जिमीजैम: यह एक सरल तरीका नहीं है यदि आप स्थिर प्रदर्शन चाहते हैं और ऐसे "अनुकूलन" SQLServer संस्करण के लिए बहुत संवेदनशील हैं। और ओरेकल (जो संस्करण?) को अपील करने में गलती न करें। ऐतिहासिक रूप से SQLServer ने पसंद किया NOT EXISTSलेकिन NOT INप्रश्नों में Oracle । लेकिन आज इसे योजना जनरेटर में त्रुटि के रूप में माना जाना चाहिए
एलेक्स यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.