SQL सर्वर NOLOCK और जुड़ता है


153

पृष्ठभूमि: मेरे पास एक प्रदर्शन-महत्वपूर्ण क्वेरी है जिसे मैं चलाना चाहता हूं और मुझे गंदे रीड की परवाह नहीं है।

मेरा सवाल यह है कि; यदि मैं जॉइन कर रहा हूं, तो क्या मुझे उन पर भी NOLOCK संकेत निर्दिष्ट करना होगा?

उदाहरण के लिए; है:

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID

के बराबर:

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b ON a.ID = b.ID

या क्या मुझे (NOLOCK)जुड़ने वाली मेज पर ताला नहीं लगाना है यह सुनिश्चित करने के लिए मुझे जुड़ने पर संकेत निर्दिष्ट करना होगा ?

जवाबों:


166

मैं READ UNCOMMITTEDतर्क को संबोधित नहीं करूंगा , बस आपका मूल प्रश्न।

हां, आपको WITH(NOLOCK)जॉइन की प्रत्येक टेबल पर जरूरत है । नहीं, आपके प्रश्न समान नहीं हैं।

इस अभ्यास को आज़माएं। लेनदेन शुरू करें और तालिका 1 और टेबल 2 में एक पंक्ति डालें। अभी तक लेन-देन न करें या रोलबैक न करें। इस बिंदु पर आपकी पहली क्वेरी सफलतापूर्वक वापस आ जाएगी और इसमें अनअमाइंड पंक्तियाँ शामिल होंगी; आपकी दूसरी क्वेरी वापस नहीं आएगी क्योंकि तालिका 2 का WITH(NOLOCK)संकेत उस पर नहीं है।


18

मुझे पूरा यकीन था कि आपको क्वेरी में NOLOCKप्रत्येक के लिए निर्दिष्ट करने की आवश्यकता है JOIN। लेकिन मेरा अनुभव SQL सर्वर 2005 तक सीमित था।

जब मैंने पुष्टि करने के लिए सिर्फ MSDN को देखा, तो मुझे कुछ भी निश्चित नहीं मिला। नीचे दिए गए कथनों से मुझे लगता है, कि 2008 के लिए, ऊपर दिए गए आपके दो कथन समतुल्य हैं, हालांकि 2005 के लिए ऐसा नहीं है:

[SQL Server 2008 R2]

सभी लॉक संकेत उन सभी तालिकाओं और विचारों के लिए प्रचारित किए जाते हैं , जिन्हें क्वेरी योजना द्वारा एक्सेस किया जाता है , जिसमें एक दृश्य में संदर्भित तालिकाएं और दृश्य शामिल हैं। साथ ही, SQL सर्वर संगत लॉक संगतता जाँच करता है।

[SQL सर्वर 2005]

SQL सर्वर 2005 में, सभी लॉक संकेत सभी तालिकाओं और विचारों के लिए प्रचारित किए जाते हैं जिन्हें एक दृश्य में संदर्भित किया जाता है। साथ ही, SQL सर्वर संगत लॉक संगतता जाँच करता है।

इसके अतिरिक्त, ध्यान दें - और यह 2005 और 2008 दोनों पर लागू होता है:

यदि तालिका क्वेरी योजना द्वारा एक्सेस नहीं की गई है, तो तालिका के संकेतों को अनदेखा कर दिया जाता है। इसका कारण यह हो सकता है कि ऑप्टिमाइज़र ने तालिका का उपयोग न करने का विकल्प चुना है, या क्योंकि इसके बजाय अनुक्रमित दृश्य एक्सेस किया गया है। उत्तरार्द्ध मामले में, एक अनुक्रमित दृश्य तक पहुंच को OPTION (EXPAND VIEWS)क्वेरी संकेत का उपयोग करके रोका जा सकता है ।


@ इन साने: दिलचस्प ... इसके लिए धन्यवाद ... मैं मान रहा हूं कि मैं इसे जॉन्स पर शामिल करके कोई नुकसान नहीं कर रहा हूं, भले ही यह पूरी तरह से आवश्यक न हो? NOLOCK पर प्रलेखन बहुत विरल है जैसा कि आपने उल्लेख किया है; मुझे खुद को निर्णायक समझने में परेशानी हुई।
DanP

2
@InSane: आपको यह जानकारी कहां से मिली? यह स्वीकृत उत्तर के खिलाफ जाता है।
जय सुलिवन

1
@notfed - उल्लेख TechNet लिंक technet.microsoft.com/en-us/library/ms187373(v=sql.105).aspx - आप डाटाबेस के विभिन्न संस्करणों के लिए एक ही लेख तुलना करने के लिए शीर्ष पर डेटाबेस संस्करण को बदल सकते हैं
Jagmag

2
2005 पाठ VIEWS के बारे में बात करता है। इसलिए यदि आप "myview with (nolock)" से करते हैं, तो यह कहता है कि nolock को सभी दृश्य और myview में शामिल किए गए विचारों के लिए प्रचारित किया गया है (आप वहां 10 जोड़ सकते हैं)। यह निश्चित नहीं है कि 2008 के पाठ का वास्तव में क्या मतलब है क्योंकि यह विचारों के अतिरिक्त "क्वेरी प्लान द्वारा एक्सेस" को जोड़ता है।
थियरी_एस

9

न तो। आप अलग-अलग स्तर निर्धारित करते हैं READ UNCOMMITTEDजो व्यक्तिगत लॉक संकेत देने से हमेशा बेहतर होता है। या, बेहतर अभी भी, यदि आप निरंतरता जैसे विवरणों की परवाह करते हैं, तो स्नैपशॉट अलगाव का उपयोग करें ।


@Remus: मुझे यकीन नहीं है कि मैं अपने मामले में READ UNCOMMITTED का उपयोग कर सकता हूं क्योंकि मैं एक विशेष कच्चे ADO.NET कॉल करने के लिए NHibernate के माध्यम से कनेक्शन का उपयोग कर रहा हूं; क्या इसे क्वेरी में इनलाइन निर्दिष्ट किया जा सकता है, या यह NHibernate लेनदेन पर मौजूद लेनदेन स्तर का पालन करेगा?
DanP

कॉल को लपेटें using (TransactionScope scope=new TransactionScope(..., TransactionOptions) {...}और IsolationLevelविकल्पों पर सेट करें: msdn.microsoft.com/en-us/library/…
Remus Rusanu

@Remus: दुर्भाग्य से, लेन-देन प्रबंधन का इस से बहुत अधिक स्तर पर ध्यान रखा जाता है, इसलिए यह भी एक विकल्प नहीं है।
DanP

समझा। फिर अपने प्रश्न का उत्तर देने के लिए: NOLOCK एक टेबल संकेत है, और जैसा कि यह उस पंक्तियों पर लागू होता है जिसमें जोड़ा जा रहा है (तालिका, दृश्य, TVF आदि)। यदि आपके पास एक क्वेरी में कई पंक्तियाँ शामिल हैं, तो प्रत्येक को अपने स्वयं के NOLOCK संकेत की आवश्यकता होगी।
रेमस रुसानु

2
लेकिन क्या आपने स्नैपशॉट अलगाव पर विचार किया है? ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON;। परिणाम शानदार हैं, जैसा कि सभी सामान्य पढ़े गए प्रतिबद्ध स्नैपशॉट रीड्स में बदल जाते हैं, लॉक फ्री अभी तक सुसंगत हैं। लागत में वृद्धि हुई है tempdbलोड: msdn.microsoft.com/en-us/library/ms175492.aspx
रेमस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.