10

हमारी टीम ने हाल ही में SQL Server 2008 से SQL Server 2012 से हमारे डेटाबेस को अपग्रेड किया है। हमने जो ब्रेकिंग परिवर्तन देखा है वह SELECT कथन द्वारा लौटाई गई पंक्तियों के डिफ़ॉल्ट क्रम में था, यानी जब खंड द्वारा एक स्पष्ट आदेश निर्दिष्ट नहीं है।SELECT क्वेरी में डिफ़ॉल्ट पंक्ति क्रम - SQL Server 2008 बनाम SQL 2012

एमएसडीएन के अनुसार, SQL Server 2012 पंक्तियों के आदेश को तब तक पूरा नहीं करता जब तक कि धारा द्वारा ऑर्डर निर्दिष्ट नहीं किया जाता है।

हमारे पास 5 डेटाबेस में 2500+ संग्रहीत प्रक्रियाएं हैं जिनके पास ऑर्डर द्वारा ऑर्डर के बिना चयन विवरण हैं और SQL Server 2008 में व्यवहार से मेल खाने के लिए मैन्युअल रूप से क्लॉज द्वारा ORDER को जोड़ने का एक बड़ा प्रयास होगा। क्या कोई सेटिंग है या ऐसा करने का तेज़ तरीका?

अन्य विकल्प, जिसे एक्सप्लोर नहीं किया गया है, को SQL Server 2008 में डाउनग्रेड करना है। यह कितना मुश्किल होगा?

+11

"डिफ़ॉल्ट पंक्ति आदेश" के रूप में ऐसी कोई चीज नहीं है। एक संबंधित तालिका में पंक्तियां *** नहीं *** क्रमबद्ध हैं। * जब तक आप डीबीएमएस द्वारा 'ऑर्डर' निर्दिष्ट नहीं करते हैं, तो उन्हें * किसी * ऑर्डर में वापस करने के लिए स्वतंत्र होता है जो यह उपयुक्त लगता है। आपका कोड शुरुआत से टूट गया था।आपकी समस्या का एकमात्र समझदार समाधान बुलेट को काटने और कोड को 'ऑर्डर' का उपयोग करने के लिए बदलना है, आप भाग्यशाली हैं कि यह बग पहले दिखाई नहीं दे रहा है। –

+0

वैसे एसक्यूएल 2008 वही है जिसमें कोई गारंटी नहीं है "डिफ़ॉल्ट" पंक्ति –

+0

क्लस्टर और गैर-क्लस्टर्ड इंडेक्स का उपयोग करने का प्रयास करें, यदि आपके पास पहले से ही आपकी तालिका में प्राथमिक कुंजी है तो आपको डिफ़ॉल्ट प्राथमिक कुंजी के रूप में क्लस्टर के बारे में चिंता करने की ज़रूरत नहीं है क्लस्टर सूचकांक है। – Chethan

उत्तर

38

आपको वापस जाना होगा और ORDER BY अपने कोड में खंड जोड़ना होगा क्योंकि उनके बिना आदेश की गारंटी नहीं है। आप अतीत में "भाग्यशाली" थे कि आपको हमेशा एक ही आदेश मिल गया था, लेकिन ऐसा इसलिए नहीं था क्योंकि SQL Server 2008 ने वैसे भी इसकी गारंटी दी थी। इसकी संभावना है कि आपकी अनुक्रमणिका के साथ या डिस्क पर डेटा कैसे संग्रहीत किया जा रहा था।

यदि आप हार्डवेयर कॉन्फ़िगरेशन में अंतर को अपग्रेड करते समय एक नए होस्ट में स्थानांतरित हो जाते हैं तो आपके प्रश्नों को निष्पादित करने के तरीके में बदलाव हो सकता है। इस तथ्य का जिक्र नहीं करना चाहिए कि नए सर्वर ने टेबल पर आंकड़ों का पुनर्मूल्यांकन किया होगा और SQL Server 2012 क्वेरी ऑप्टिमाइज़र संभवतः SQL Server 2008 में किसी चीज़ की तुलना में थोड़ा अलग करता है।

यह एक झूठ है कि आप भरोसा कर सकते हैं एसक्यूएल में सेट किए गए परिणाम का क्रम स्पष्ट रूप से उस ऑर्डर को स्पष्ट किए बिना सेट करें जिसे आप चाहते हैं। एसक्यूएल परिणाम कभी एक ऑर्डर है जिसे आप ORDER BY खंड का उपयोग किए बिना भरोसा कर सकते हैं। एसक्यूएल सेट सिद्धांत के आसपास बनाया गया है। क्वेरी परिणाम मूल रूप से सेट होते हैं (या बहु-सेट)।

Itzik बेन-गण, एक अच्छा अपनी पुस्तक Microsoft SQL Server 2012 T-SQL Fundamentals

सेट सिद्धांत है, जो गणितज्ञ जोर्ज कैंटर के साथ उत्पन्न में एसक्यूएल के संबंध में सेट सिद्धांत के विवरण देता है गणितीय शाखाओं के एक है जिस पर संबंध मॉडल आधारित है। एक सेट के कैंटर की परिभाषा इस प्रकार है:

तक एक "सेट" हम निश्चित, विशिष्ट वस्तुओं मीटर में हमारी धारणा की या हमारे विचारों की (जो एम के "तत्वों" कहा जाता है) की एक पूरी में मतलब किसी भी संग्रह एम । - जोसेफ डब्ल्यू Dauben और जोर्ज कैंटर (प्रिंसटन यूनिवर्सिटी प्रेस, 1990)

बाद परिभाषा पदों की एक विस्तृत विवरण Itzik तो पर चला जाता है कहने के लिए:

एक किस कैंटर की परिभाषा पत्तियां सेट करना शायद जितना महत्वपूर्ण है उतना महत्वपूर्ण है। ध्यान दें कि परिभाषा सेट तत्वों के बीच किसी भी क्रम का उल्लेख नहीं करती है। जिस क्रम में सेट तत्व सूचीबद्ध हैं, वह अपमानजनक नहीं है। सेट तत्वों को सूचीबद्ध करने के लिए औपचारिक नोटेशन घुंघराले ब्रैकेट का उपयोग करता है: {ए, बी, सी}। चूंकि ऑर्डर में कोई प्रासंगिकता नहीं है, इसलिए आप उसी सेट को {b, a, c} या {b, c, a} के रूप में व्यक्त कर सकते हैं। गुणों (एसक्यूएल में कॉलम कहा जाता है) के आगे बढ़ते हुए संबंध (एसक्यूएल में एक टेबल कहा जाता है) का हेडर बनाते हैं, एक तत्व को नाम से पहचाना जाना चाहिए - सामान्य स्थिति नहीं। इसी तरह, tuples (एसक्यूएल द्वारा पंक्तियों कहा जाता है) के सेट पर विचार करें जो संबंध के शरीर को बनाते हैं; एक तत्व को इसके प्रमुख मानों द्वारा पहचाना जाता है - स्थिति के अनुसार नहीं। कई प्रोग्रामर को इस विचार को स्वीकार करने में कठिनाई होती है कि, सम्मान तालिकाओं के लिए, पंक्तियों के बीच कोई आदेश नहीं है। जब तक आप स्पष्ट का अनुरोध कि डेटा एक विशिष्ट तरीके से हल हो दूसरे शब्दों में, एक टेबल के खिलाफ एक प्रश्न किसी भी क्रम में पंक्तियों को वापस कर सकते हैं, शायद प्रस्तुति प्रयोजनों के लिए।

लेकिन सेट के अकादमिक परिभाषा के बावजूद SQL सर्वर में कार्यान्वयन ने परिणामों में किसी भी आदेश की गारंटी नहीं दी है। यह MSDN blog post from 2005 by a member of the query optimizer team बताता है कि आपको इंटरमीडिएट ऑपरेशंस से ऑर्डर पर भरोसा नहीं करना चाहिए।

पुनर्व्यवस्था नियमों और इस धारणा का उल्लंघन कर सकते हैं (और इसलिए करते हैं जब यह आप, डेवलपर के लिए असुविधाजनक है;)। कृपया समझें कि जब हम एक और अधिक कुशल योजना खोजने के लिए संचालन को पुन: व्यवस्थित करते हैं, तो हम पेड़ में मध्यवर्ती नोड्स के लिए ऑर्डरिंग व्यवहार को बदल सकते हैं। यदि आपने पेड़ में एक ऑपरेशन किया है जो विशेष इंटरमीडिएट ऑर्डरिंग मानता है, तो यह टूट सकता है।

कोनोर कनिंघम (वास्तुकार, एसक्यूएल सर्वर कोर इंजन) द्वारा इस ब्लॉग पोस्ट "No Seatbelt - Expecting Order without ORDER BY" एसक्यूएल सर्वर के बारे में है 2008 वह एक भी सूचकांक हमेशा में पंक्तियों को वापस करने के लिए लगता है कि साथ में यह 20k पंक्तियों के साथ एक मेज है वहीआज्ञा। क्वेरी में ORDER BY जोड़ने से निष्पादन योजना भी परिवर्तित नहीं होती है, इसलिए यह ऑप्टिमाइज़र को यह समझने की आवश्यकता नहीं है कि क्वेरी को अधिक महंगा बनाने में कोई जोड़ने की तरह नहीं है। लेकिन एक बार जब वह मेज पर एक और 20k पंक्तियों को जोड़ता है तो अचानक क्वेरी योजना बदल जाती है और अब यह समांतरता का उपयोग करती है और परिणाम अब आदेश नहीं दिए जाते हैं!

यहाँ कठिन हिस्सा किसी भी बाहरी उपयोगकर्ता पता करने के लिए जब एक योजना बदल जाएगा के लिए कोई उचित तरीका है कि वहाँ है। सभी योजनाओं का स्थान विशाल है और आपके सिर को सोचने के लिए दर्द होता है। यदि पर्याप्त पैरामीटर बदलते हैं, तो SQL सर्वर का ऑप्टिमाइज़र योजनाओं को सरल प्रश्नों के लिए भी बदल देगा। आप भाग्यशाली हो सकते हैं और कोई योजना परिवर्तन नहीं हो सकता है, या आप इस समस्या के बारे में सोच सकते हैं और ORDER BY जोड़ सकते हैं।

आप अधिक ठोस की जरूरत है तो बस इन पदों पढ़ें:

+0

उस आदेश की गारंटी नहीं है। कई कारक क्वेरी परिणामों के क्रम को प्रभावित कर सकते हैं और आप उन सभी की अपेक्षा नहीं कर सकते हैं। आप थोड़ी देर के लिए और शायद हमेशा के लिए भाग्यशाली हो सकता है। लेकिन 'ऑर्डर बी' क्लॉज जोड़ना प्रदर्शन को प्रभावित नहीं करेगा यदि क्वेरी ऑप्टिमाइज़र को यह एहसास हो कि इसकी आवश्यकता नहीं है। क्या यह जोखिम चलाने के लायक है कि चीजें अप्रत्याशित रूप से तोड़ जाएंगी क्योंकि आप अपनी क्वेरी पर 'ऑर्डर बाय' डालने की तरह महसूस नहीं करते हैं? –

+2

मुझे नहीं पता कि आप इस तथ्य में क्या महत्व रखते हैं कि तालिका सूचकांक के साथ आपकी सरल क्वेरी आपकी अपेक्षा के अनुसार पंक्तियों को वापस लाती है। मैंने कहां नहीं कहा है कि यह आपके आदेश की अपेक्षा कभी बाहर नहीं आएगा। SQL सर्वर आर्किटेक्ट्स में से किसी एक से मेरे उत्तर में अंतिम उद्धरण दोहराएं। 'ऑर्डर बाय' क्लॉज के बिना आपके परिणाम सेट का ऑर्डर किसी भी समय कई कारणों से बदल सकता है कि आप यह नहीं जान सकते कि यह कब होगा। आप जो कह रहे हैं वह बुरी सलाह है और इसे उत्पादन प्रणाली में इस्तेमाल नहीं किया जाना चाहिए। ऑर्डर करने के लिए इंडेक्स पर भरोसा न करें। यदि आपको ऑर्डर किए गए परिणाम सेट की आवश्यकता है तो 'ORDER BY' –

+1

@ सेंथिलप्रभू का उपयोग करें यह एक तथ्य है कि आप खंड द्वारा ऑर्डर द्वारा निर्दिष्ट किए बिना सॉर्ट ऑर्डर की गारंटी नहीं दे सकते। भले ही यह 99.99% समय होता है, यह 100% नहीं है, यह सिर्फ भाग्य है, और एक सरल परीक्षण केस है। कृपया अपनी टिप्पणी बदलें। यह बहुत महत्वपूर्ण है कि इस उत्तर को पढ़ने वाले अन्य लोग इसे समझते हैं, अगर आप सॉर्ट ऑर्डर पर भरोसा करते हैं, तो आपको स्पष्ट रूप से अपने परिणामों को ऑर्डर करना चाहिए। यह "एसक्यूएल 2016 में काम नहीं कर रहा है"। यह किसी भी संस्करण में काम नहीं करता है, यह पूरी तरह से पूछताछ करने के लिए क्वेरी इंजन पर निर्भर करता है कि परिणाम लौटाए जाते हैं, जब तक कि आप आदेश नहीं देते। यहां आपकी टिप्पणियां सिर्फ लोगों को भ्रमित कर देगी। – Davos

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