SQL सर्वर 2012 में रिक्त परिणाम के साथ क्वेरी त्रुटि क्यों होती है?


31

MS SQL Server 2012 में निम्न क्वेरीज़ चलाते समय दूसरी क्वेरी विफल हो जाती है लेकिन पहले नहीं। इसके अलावा, जब बिना क्लॉस चलाए दोनों क्वेरी फेल हो जाएंगी। मैं एक नुकसान में हूं कि या तो विफल हो जाएगा क्योंकि दोनों के पास खाली परिणाम सेट होना चाहिए। किसी भी मदद / अंतर्दृष्टि की सराहना की है।

create table #temp
(id     int primary key)

create table #temp2
(id     int)

select 1/0
from #temp
where id = 1

select 1/0
from #temp2
where id = 1

जवाबों:


39

निष्पादन योजनाओं पर एक प्रारंभिक नज़र यह दर्शाती है कि अभिव्यक्ति 1/0गणना स्केलर ऑपरेटरों में परिभाषित की गई है:

चित्रमय योजनाएँ

अब, भले ही निष्पादन योजनाएं बाईं ओर चलना शुरू कर देती हैं, पुनरावृत्तियां बुला रही हैं Openऔर GetRowपरिणामों को वापस करने के लिए बाल पुनरावृत्तियों पर विधियाँ, SQL सर्वर 2005 और बाद में एक अनुकूलन होता है, जिसमें अभिव्यक्तियाँ अक्सर केवल गणना स्केलर द्वारा परिभाषित की जाती हैं, मूल्यांकन बाद में स्थगित कर दिया जाता है ऑपरेशन के परिणाम की आवश्यकता है :

SET सांख्यिकी XML द्वारा उत्पन्न Showplans में दिखाई देने वाली गणना Scalar ऑपरेटरों में RunTimeInformation तत्व नहीं हो सकता है।  जब SQL सर्वर प्रबंधन स्टूडियो में वास्तविक निष्पादन योजना विकल्प शामिल किया जाता है, तो चित्रमय शोप्लान्स में, वास्तविक पंक्तियाँ, वास्तविक रिबाइंड और वास्तविक रिवाइंड्स गुण विंडो से अनुपस्थित हो सकते हैं।  जब ऐसा होता है, तो इसका मतलब है कि हालांकि इन ऑपरेटरों का उपयोग संकलित क्वेरी योजना में किया गया था, लेकिन उनके कार्यों को रन-टाइम क्वेरी योजना में अन्य ऑपरेटरों द्वारा किया गया था।  यह भी ध्यान दें कि SET STATISTICS PROFILE द्वारा उत्पन्न Showplan आउटपुट में निष्पादित होने की संख्या SET STATISTICS XML द्वारा उत्पन्न Showplans में रिबाइंड और रिवाइंड की राशि के बराबर है।  से: MSDN पुस्तकें ऑनलाइन

इस मामले में, अभिव्यक्ति परिणाम केवल तब आवश्यक होता है जब ग्राहक को वापसी के लिए पंक्ति को इकट्ठा किया जाता है (जिसे आप ग्रीन SELECTआइकन पर होने के बारे में सोच सकते हैं )। उस तर्क से, आस्थगित मूल्यांकन का मतलब होगा कि अभिव्यक्ति का मूल्यांकन कभी नहीं किया जाता है क्योंकि न तो योजना एक वापसी पंक्ति उत्पन्न करती है। बिंदु को थोड़ा श्रम करने के लिए, न तो क्लस्टर इंडेक्स सीक और न ही टेबल स्कैन एक पंक्ति लौटाता है, इसलिए क्लाइंट के पास लौटने के लिए इकट्ठा करने के लिए कोई पंक्ति नहीं है।

हालांकि, एक अलग अनुकूलन है जिससे कुछ अभिव्यक्तियों को रनटाइम स्थिरांक के रूप में पहचाना जा सकता है और इसलिए क्वेरी निष्पादन शुरू होने से पहले एक बार मूल्यांकन किया जाता है । इस स्थिति में, यह एक संकेत है कि शोप्पन एक्सएमएल में पाया जा सकता है (बाईं ओर क्लस्टर इंडेक्स सीक प्लान, दाईं ओर टेबल स्कैन प्लान):

एक्सप्लेन एक्सएमएल

मैंने अंतर्निहित तंत्रों के बारे में अधिक लिखा है और वे इस ब्लॉग पोस्ट में प्रदर्शन को कैसे प्रभावित कर सकते हैं । वहां दी गई जानकारी का उपयोग करके, हम पहली क्वेरी को संशोधित कर सकते हैं ताकि निष्पादन शुरू होने से पहले दोनों अभिव्यक्तियों का मूल्यांकन और कैश किया जाए:

select 1/0 * CONVERT(integer, @@DBTS)
from #temp
where id = 1

select 1/0
from #temp2
where id = 1

अब, पहली योजना में एक निरंतर अभिव्यक्ति संदर्भ भी शामिल है, और दोनों प्रश्न त्रुटि संदेश का उत्पादन करते हैं। पहली क्वेरी में XML शामिल है:

लगातार अभिव्यक्ति

अधिक जानकारी: गणना स्केलर, एक्सप्रेशन और प्रदर्शन


21

मैं समझदारी से अनुमान लगाने जा रहा हूं (और इस प्रक्रिया में संभवतः एक SQL सर्वर गुरु को आकर्षित कर सकता हूं जो वास्तव में विस्तृत जवाब दे सकता है)।

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

  1. प्राथमिक कुंजी सूचकांक को स्कैन करें
  2. क्वेरी के लिए आवश्यक डेटा तालिका में मान देखें

यह इस पथ को चुनता है क्योंकि आपके पास whereप्राथमिक कुंजी पर एक खंड है। यह कभी भी दूसरे चरण पर नहीं जाता है, इसलिए क्वेरी विफल नहीं होती है।

दूसरे के पास चलाने के लिए एक प्राथमिक कुंजी नहीं है, इसलिए यह क्वेरी को इस रूप में बताता है:

  1. डेटा की एक पूर्ण तालिका स्कैन करें और आवश्यक मान पुनः प्राप्त करें

उन मूल्यों में 1/0से एक समस्या पैदा कर रहा है।

यह SQL सर्वर क्वेरी को अनुकूलित करने का एक उदाहरण है। अधिकांश भाग के लिए, यह एक अच्छी बात है। SQL सर्वर selectतालिका स्कैन ऑपरेशन में स्थितियों को स्थानांतरित करेगा । यह अक्सर क्वेरी के मूल्यांकन में चरणों को बचाता है।

लेकिन, यह अनुकूलन एक अच्छी बात नहीं है। वास्तव में, यह SQL सर्वर प्रलेखन का उल्लंघन करने के लिए लगता है जो कहता है कि इस whereखंड का मूल्यांकन पहले किया गया है select। खैर, उनके पास इसके अर्थ के बारे में कुछ स्पष्ट व्याख्या हो सकती है। अधिकांश मनुष्यों के लिए, हालांकि, तार्किक रूप से whereपहले प्रसंस्करण का selectअर्थ होगा (अन्य चीजों के बीच) "उन selectपंक्तियों पर -clause त्रुटियों को उत्पन्न न करें जो उपयोगकर्ता को वापस नहीं आती हैं"।


1
+1 कोई सुराग नहीं अगर आप सही हैं, लेकिन सबसे अच्छा जवाब मैं देख सकता हूं कि अंतर केवल प्राथमिक कुंजी है।

1
@GordonLinoff पॉल रैंडल ने ट्विटर के माध्यम से पुष्टि की कि आपका जवाब धमाकेदार था।
श्मिटज

4
@Still, निष्पादन का वास्तविक क्रम, हालांकि अलग-अलग, उस तरह के त्रुटि संदेश नहीं होने चाहिए।
ypercube y

7
@ypercube Erland Sommarskog होगा आपसे सहमत (कनेक्ट आइटम)
पॉल व्हाइट GoFundMonica कहते

2
पॉइंटर के लिए धन्यवाद - मैंने लॉग इन किया और अनुरोध को बढ़ा दिया।
गॉर्डन लिनॉफ़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.