NOLOCK संकेत रिकॉर्ड का क्रम बदल दिया है


11

टेबल Clientफ़ील्ड पर एक क्लस्टर इंडेक्स है LastName

जब मैं केवल तालिका से सभी रिकॉर्ड को डंप करता हूं, तो वे वर्णमाला के क्रम में दिखाई देते हैं जब तक (nolock)कि प्रश्न में प्रश्न के रूप में संकेत का उपयोग नहीं किया जाता है। वह संकेत रिकॉर्ड के क्रम को बदल देता है। इसे होना चाहिए?। मैं सकारात्मक हूं कि किसी भी अन्य सत्र का उस तालिका में परिवर्तन के साथ एक खुला लेनदेन sp_who2नहीं है (कम से कम मुझे कोई भी नहीं दिखा रहा है)।

आदेश में अंतर कैसे समझाया जा सकता है?

टिप्पणियों से खींची गई अतिरिक्त जानकारी:

  1. द्वारा कोई आदेश नहीं है। क्या गैर-संकुलित सूचकांक को लागू करना चाहिए?

  2. अनुक्रमणिका संकेत का उपयोग करते समय भी प्रश्न अलग-अलग क्रम में लौटाते हैं, एक संकुल सूचकांक को निर्दिष्ट करते हुए। क्या उन्हें चाहिए? मैं सोच रहा हूं कि nolockयोजनाओं के दृश्यमान परिवर्तन के बिना लौटाए गए अभिलेखों का क्रम क्यों बदल जाता है।

  3. मैंने उन पर एक WinDiff किया - सिवाय [] (nolock)[क्वेरी संकेत] के।


21
संकेत आदेश को नहीं बदलता है - क्योंकि ऐसा कोई आदेश नहीं है जिसे बदला जा सकता है
a_horse_with_no_name

जवाबों:


47

एक आदेश परिणाम सेट की उपस्थिति, एक ORDER BYखंड के बिना , अक्सर सूचकांक क्रम में पंक्तियों को स्कैन करने वाली स्कैन से परिणाम होता है। एक इंडेक्स-ऑर्डर स्कैन को आमतौर पर डिफ़ॉल्ट READ COMMITTEDआइसोलेशन स्तर के तहत क्यों चुना जाता है, इसका कारण यह है कि यह अवांछित कंसीलर विसंगतियों की संभावना को कम कर देता है जैसे कि एक ही पंक्ति को कई बार एनकाउंटर करना, या कुछ पंक्तियों को पूरी तरह से छोड़ देना। यह कई स्थानों पर विस्तृत है, जिसमें अलगाव स्तरों के बारे में लेखों की श्रृंखला शामिल है।

एक साथ NOLOCKतालिका संकेत, इस व्यवहार में ढील है, और तालिका के लिए उपयोग अधिक सहिष्णु के तहत किया जाता है READ UNCOMMITTEDअलगाव के स्तर है, जो हो सकता है आवंटन के क्रम में डेटा स्कैन के बजाय सूचकांक आदेश। जैसा कि उस लिंक में वर्णित है, एक आवंटन-ऑर्डर या इंडेक्स-ऑर्डर स्कैन का उपयोग करने के बारे में निर्णय भंडारण इंजन पर छोड़ दिया गया है। यह विकल्प क्वेरी प्लान में बदलाव के बिना निष्पादन के बीच बदल सकता है ।

यह बहुत ही सारगर्भित लग सकता है, लेकिन एडवेंचरवर्क्स 2012 डेटाबेस के खिलाफ अनडूएक्टेड फ़ंक्शंस का उपयोग करके कुछ प्रश्नों के साथ अधिक आसानी से प्रदर्शित किया जा सकता है

USE AdventureWorks2012;
GO
-- Appears to be ordered by BusinessEntityID
-- File:Page:Slot goes up and down several times
-- Show physical locations with sys.fn_PhysLocFormatter (undocumented)
SELECT
    P.BusinessEntityID,
    [(File:Page:Slot)] =
        sys.fn_PhysLocFormatter(%%physloc%%)
FROM Person.Person AS P;

-- Same query with TABLOCK or NOLOCK
-- Allocation-order (IAM) scan
-- Now appears to be ordered by File:Page:Slot instead of BusinessEntityID
SELECT P.BusinessEntityID,
    [(File:Page:Slot)] =
        sys.fn_PhysLocFormatter(%%physloc%%)
FROM Person.Person AS P WITH (NOLOCK);

क्वेरी परिणाम

पॉल व्हाइट से मामूली संशोधन के साथ प्रश्नों को उधार लिया गया है ।

अंत में, बस स्पष्ट होने के लिए, यह उत्तर एक निर्धारित परिणाम सेट की उपस्थिति के बारे में है । वहाँ है कोई गारंटी प्रस्तुति आदेश एक शीर्ष स्तर के बिना ORDER BY

एक आबंटन-ऑर्डर स्कैन कई अन्य परिस्थितियों में हो सकता है, जैसे कि जब एक टेबल-लेवल लॉक हासिल किया जाता है, या डेटाबेस केवल-पढ़ने के लिए मोड में होता है। समानांतरवाद उस आदेश को भी प्रभावित कर सकता है जिसमें डेटा वापस आ जाता है। मुख्य बिंदु यह है कि बिना ORDER BY, ऑर्डर डेटा वापस लौटाए बिना समय के साथ भिन्न हो सकता है।


7
अच्छा, मेरे अप्राप्य प्रयास से बहुत अधिक विशिष्ट। क्रुक्स आपके अंतिम दो पैराग्राफ में है, निश्चित रूप से। "क्यों मैं वास्तव में अंत में कोई फर्क नहीं पड़ता। हो सकता है कि आपके पास उस कॉर्ड से बेहतर भाग्य होगा जो मैंने किया था।
हारून बर्ट्रेंड

12

जब मैं केवल मेज से सभी रिकॉर्ड डंप करता हूं

... तो आपको किसी आदेश की उम्मीद नहीं करनी चाहिए। वास्तव में एक ही क्वेरी कई बार चलने पर बिना किसी चेतावनी के एक अलग क्रम में वापस आ सकती है। कारण यह है कि आपके दो प्रश्न - जो "अलग-अलग" प्रश्न हैं, जो अलग-अलग क्वेरी टेक्स्ट के कारण संभव हैं, न कि संकेत के कारण - अलग-अलग निष्पादन योजनाएं हैं (और अंतर सूक्ष्म हो सकता है, जैसे कि एक पुनरावृत्ति जो इसमें समान दिखता है दोनों की योजना है, लेकिन ordered: trueकेवल एक में है, या अनुमानित पंक्तियों की एक विशाल भिन्न संख्या है क्योंकि एक प्रमुख डेटा परिवर्तन से पहले संकलित किया गया था)। यह भी हो सकता है कि एक आवंटन आदेश स्कैन लिया जा रहा है, क्योंकि जेम्स ने अपने उत्तर में सही बताया है।

किसी भी स्थिति में, चूंकि आप बिना क्वेरी के चल रहे हैं ORDER BY, SQL सर्वर आपके आदेश की परवाह नहीं करता है, और इसलिए बंद हो जाता है और पंक्तियों को वापस करने का सबसे कुशल तरीका निर्धारित करता है (यदि आप नहीं करते हैं तो यह आदेश की परवाह नहीं करता है )।

मुझे यह स्पष्ट करने दें:

यदि आप एक निश्चित आदेश चाहते हैं या अपेक्षा करते हैं, तो एक आदेश जोड़ें खंड द्वारा

यह पहले आया है:

और मैंने इसके बारे में ब्लॉग किया है:

यहाँ उत्तरार्द्ध का एक उद्धरण है जो एक ORDER BYखंड के बजाय एक सूचकांक संकेत का उपयोग करने के बारे में आपकी टिप्पणी को संबोधित करने के लिए मैंने क्या दोहराया है :

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

कॉनर कनिंघम - एक बहुत होशियार आदमी, जो SQL सर्वर के लिए सीधे तौर पर जिम्मेदार होता है, जब वह आपके लिए एक प्रश्न की प्रक्रिया करता है - यहाँ भी इसके बारे में ब्लॉग किया है:

कृपया कुछ पढ़ने और फिर ORDER BYअलग या अप्रत्याशित छँटाई के बारे में शिकायत करने से पहले अपने प्रश्नों का एक खंड जोड़ें ।


11

जेम्स ने अच्छी तरह से समझाया कि यह कैसे काम करता है, लेकिन मैं सिर्फ एक बात को दोहराना चाहूंगा: जब तक आप एक ऑर्डरिंग फ़ंक्शन का उपयोग नहीं करते, परिणाम सेट में पंक्तियों का क्रम अपरिभाषित है । यदि आपको दिए गए आदेश की आवश्यकता है, तो एक स्पष्ट order byक्लॉज़ का उपयोग करें - यदि आप इसे निर्दिष्ट नहीं करते हैं, तो आप मूल रूप से कह रहे हैं "मैं ऑर्डर के बारे में बिल्कुल परवाह नहीं करता हूं", न कि "इसे क्लस्टर इंडेक्स द्वारा ऑर्डर करें"।

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