2010-09-24 16 views
118

पृष्ठभूमि में शामिल है: मेरे पास एक प्रदर्शन-महत्वपूर्ण क्वेरी है जिसे मैं चलाने के लिए चाहता हूं और मुझे गंदे पढ़ने की परवाह नहीं है।SQL सर्वर 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) संकेत निर्दिष्ट करने के लिए की आवश्यकता होगी?

उत्तर

116

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

हां, आपको शामिल होने की प्रत्येक तालिका पर WITH(NOLOCK) की आवश्यकता है। नहीं, आपके प्रश्न समान नहीं हैं।

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

+1

धन्यवाद, बस इस मामले में जो मैं खोज रहा था। – DanP

14

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

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

[एसक्यूएल सर्वर 2008 R2]

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

[SQL सर्वर 2005]

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

साथ ही, बिंदु नोट करने के लिए - और यह 2005 और 2008 दोनों पर लागू होता है:

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

+0

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

+2

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

+0

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

8

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

+0

@ रीमस: मुझे यकीन नहीं है कि मैं अपने मामले में पढ़ा गया पढ़ाई का उपयोग कर सकता हूं क्योंकि मैं विशेष कच्चे एडीओ.NET कॉल करने के लिए एनएचबीर्नेट के माध्यम से कनेक्शन तक पहुंच रहा हूं; क्या इसे क्वेरी में इनलाइन निर्दिष्ट किया जा सकता है, या क्या यह एनएचबीर्नेट लेनदेन पर मौजूद लेनदेन स्तर का पालन करेगा? – DanP

+0

'उपयोग (लेनदेनस्कोप स्कोप = नया लेनदेनस्कोप (..., लेनदेन विकल्प) {...}' में कॉल को लपेटें और विकल्पों पर 'अलगाव लेवल' सेट करें: http://msdn.microsoft.com/en-us/ लाइब्रेरी/system.transactions.transactionoptions.isolationlevel.aspx –

+0

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