2012-09-26 9 views
48

मुझे आश्चर्य है कि तालिका में SELECT WITH (NOLOCK) का उपयोग करने का क्या फायदा है यदि उस तालिका को प्रभावित करने वाले अन्य प्रश्न SELECT प्रश्न हैं।SELECT प्रश्नों पर SQL सर्वर LOCKS को समझना

एसक्यूएल सर्वर द्वारा इसे कैसे संभाला जाता है? SELECT क्वेरी SELECT क्वेरी को अवरुद्ध करें?

मैं SQL सर्वर 2012 और एक लिंक-टू-एसक्यूएल DataContext का उपयोग कर रहा हूं।

(संपादित)

प्रदर्शन के बारे में:

  • एक 2 SELECT एक 1st SELECT एक बंद SELECT का उपयोग कर यदि समाप्त होने की प्रतीक्षा करने के लिए है?
  • बनाम SELECT WITH (NOLOCK)?

धन्यवाद।

उत्तर

111

एक SELECT एसक्यूएल सर्वर तालिका पंक्ति पर एक साझा ताला स्थापित करेंगे में - और एक दूसरे SELECT भी एक साझा लॉक की आवश्यकता होगी, और उन एक दूसरे के साथ संगत कर रहे हैं।

तो कोई नहीं - SELECT अन्य SELECT को अवरुद्ध नहीं कर सकता है।

WITH (NOLOCK) क्वेरी संकेत का उपयोग उस डेटा को पढ़ने में सक्षम होना है जो डालने की प्रक्रिया में है (किसी अन्य कनेक्शन द्वारा) और अभी तक यह नहीं किया गया है।

कि क्वेरी संकेत के बिना, एक SELECT चल रहे एक INSERT (या UPDATE) बयान है कि पंक्तियों पर एक अनन्य ताला (या शायद एक पूरी तालिका) स्थानों से एक मेज पढ़ने अवरुद्ध हो सकता है, जब तक कि आपरेशन के लेन-देन किया गया है (या वापस लुढ़का)। WITH (NOLOCK) संकेत के

समस्या है: आप डेटा पंक्तियों कि अंत (INSERT लेनदेन वापस लुढ़का है) में, सब पर सम्मिलित करने के लिए नहीं जा रहे हैं पढ़ने हो सकता है - तो अपने जैसे रिपोर्ट उस डेटा को दिखा सकती है जो वास्तव में डेटाबेस के लिए प्रतिबद्ध नहीं है।

एक अन्य प्रश्न संकेत है जो उपयोगी हो सकता है - WITH (READPAST)। यह SELECT कमांड को किसी भी पंक्तियों को छोड़ने के लिए निर्देश देता है जो इसे पढ़ने का प्रयास करता है और जो विशेष रूप से बंद कर दिया जाता है। SELECT अवरुद्ध नहीं होगा, और यह किसी भी "गंदे" गैर-प्रतिबद्ध डेटा को नहीं पढ़ेगा - लेकिन यह कुछ पंक्तियों को छोड़ सकता है, उदा। तालिका में अपनी सभी पंक्तियां न दिखाएं।

+1

अच्छा जवाब, बहुत बहुत धन्यवाद! बिना किसी कारण के '' (NOLOCK) 'का उपयोग करने के लिए कोई प्रभाव होगा (सैकड़ों' चयन 'प्रश्नों पर)? –

+1

हम अपने चुने हुए 99.5% में नाकॉक के साथ उपयोग करते हैं, कोई मजाक नहीं। यदि कोई व्यवस्थापक उपयोगकर्ता रिकॉर्ड अपडेट कर रहा है, तो आप नहीं चाहते हैं कि रिपोर्ट वहां बैठे और पूरे वितरित लेनदेन को समाप्त करने की प्रतीक्षा करें। तो उनका पुराना डेटा रिपोर्ट पर दिखाई देता है। किसे पड़ी है? अगर रिपोर्ट एक ही डेटा से पहले एक सेकंड चलाया गया था जो कि रॉकॉक के साथ होता। एकमात्र जगह यह चिंता का विषय है जो अभी तक प्रतिबद्ध नहीं है। यदि आप "आखिरी घंटे में ऑर्डर" दिखा रहे हैं जो संभावित रूप से एक मुद्दा हो सकता है, लेकिन गति/समेकन लाभ की तुलना में एक छोटा, छोटा मुद्दा। –

+2

चूंकि 'रिपोर्ट' को उदाहरण के रूप में बाहर निकाला गया था, इसलिए रिपोर्ट आम तौर पर एक समयावधि के लिए होती है जो पिछले 5 मिनट नहीं होती है। पिछले महीने से नोलॉक के साथ डेटा पर रिपोर्टिंग - ठीक है, ऐसा नहीं है कि डेटा एक महीने बाद रोलबैक पर जा रहा है। –

1

कोई लॉक के साथ चयन करें - रिकॉर्ड का चयन करेगा जो डाला जा सकता है/नहीं। आप एक गंदे डेटा पढ़ेंगे।

उदाहरण के लिए - मान लें कि एक लेनदेन 1000 पंक्तियों को सम्मिलित करता है और फिर विफल रहता है।

जब आप चुनते हैं - आपको 1000 पंक्तियां मिलेंगी।

+0

लेकिन यदि उस तालिका में कोई रिकॉर्ड डालने का इरादा नहीं है, तो क्या कोई लॉक अभी भी प्रासंगिक नहीं है? –

+0

नहीं, यह नहीं है। चूंकि पढ़ा एक साझा लॉक का उपयोग करता है जिसे 1 से अधिक सत्रों द्वारा अधिग्रहित किया जा सकता है। गंदे डेटा प्राप्त करने का कोई तरीका नहीं है। –

+0

और प्रदर्शन पीओवी पर? –

6

मेरे काम पर, हमारे पास एक बहुत बड़ी प्रणाली है जो एक ही समय में कई पीसी पर चलती है, जिसमें हजारों पंक्तियों के साथ बहुत बड़ी टेबल और कई बार पंक्तियां होती हैं।

जब आप एक बहुत बड़ी मेज पर एक चयन करते हैं, तो मान लें कि आप पिछले 10 वर्षों में उपयोगकर्ता द्वारा किए गए प्रत्येक लेनदेन को जानना चाहते हैं, और तालिका की प्राथमिक कुंजी एक कुशल तरीके से नहीं बनाई गई है, क्वेरी चलाने के लिए कई मिनट लग सकते हैं।

फिर, हमारा आवेदन मुझे एक ही समय में कई उपयोगकर्ता के पीसी पर चल रहा है, उसी डेटाबेस तक पहुंच सकता है। तो अगर कोई उस तालिका में सम्मिलित करने का प्रयास करता है जो अन्य चयन पढ़ रहा है (उन पृष्ठों में जो SQL पढ़ना चाहते हैं), तो एक LOCK हो सकता है और दो लेन-देन एक-दूसरे को अवरुद्ध कर सकते हैं।

हमें अपने चयन कथन में "कोई लॉक" नहीं जोड़ना पड़ा, क्योंकि यह एक टेबल पर एक विशाल चयन था जिसे एक ही समय में बहुत से उपयोगकर्ताओं द्वारा बहुत उपयोग किया जाता था और हमारे पास हर समय LOCKS था।

मुझे नहीं पता कि मेरा उदाहरण पर्याप्त स्पष्ट है या नहीं? यह एक वास्तविक जीवन उदाहरण है।

+0

उदाहरण के लिए धन्यवाद, लेकिन मैं केवल अन्य चयन प्रश्नों (उसी तालिका पर) को प्रभावित करने वाले SELECT प्रश्नों के बारे में सोच रहा हूं .. –

+1

वे नहीं करेंगे, लेकिन एक चुनिंदा कथन लेनदेन का हिस्सा हो सकता है जिसमें एक अद्यतन शामिल है । टीबीएल सेट एक्स = अद्यतन करें (टीबीएल से अधिकतम (वाई) का चयन करें) जहां z = (टीबीएल से न्यूनतम (ए) चुनें)। यदि आपके पास टीबीएल से समवर्ती चयन जेड है तो अन्य चयन इसे अवरुद्ध नहीं कर रहे हैं, लेकिन अपडेट है। –

+0

मेरे पास वास्तव में यह मुद्दा था कि लंबे समय तक चलने वाला चयन मेरे आवेषण को अवरुद्ध कर रहा था – nojetlag

22

प्रदर्शन पर आप चयन पर ध्यान केंद्रित करते रहते हैं।
साझा किए गए ब्लॉक को अवरुद्ध नहीं करता है।
साझा लॉक ब्लॉक अद्यतन।
यदि आपके पास सैकड़ों साझा लॉक हैं तो यह एक विशेष लॉक प्राप्त करने के लिए थोड़ी देर के लिए अपडेट करने जा रहा है क्योंकि इसे साझा लॉक को साफ़ करने के लिए प्रतीक्षा करनी होगी।

डिफ़ॉल्ट रूप से एक चयन (पढ़ा) साझा लॉक लेता है।
साझा (एस) ताले एक संसाधन को पढ़ने (चयन) पढ़ने के लिए समवर्ती लेनदेन की अनुमति देते हैं।
एक साझा लॉक अन्य चयनों (1 या 1000) पर कोई प्रभाव नहीं है।

अंतर यह है कि कैसे नॉकॉक बनाम लॉक प्रभाव अपडेट या ऑपरेशन डालें।

संसाधन पर साझा (एस) ताले मौजूद होने पर कोई अन्य लेनदेन डेटा को संशोधित नहीं कर सकता है।

एक साझा लॉक अद्यतन को अवरुद्ध करता है!
लेकिन नोलॉक अद्यतन को अवरुद्ध नहीं करता है।

इससे अपडेट के प्रदर्शन पर बहुत अधिक प्रभाव पड़ सकता है। यह आवेषण को भी प्रभावित करता है।

गंदे पढ़ने (नोलॉक) बस गंदा लगता है। आपको कभी भी आंशिक डेटा नहीं मिल रहा है। यदि कोई अपडेट जॉन को सैली में बदल रहा है तो आप कभी भी जॉली नहीं ले पाएंगे।

मैं साझा लॉक को समवर्तीता के लिए बहुत उपयोग करता हूं। जैसे ही इसे पढ़ा जाता है, डेटा खराब हो जाता है। जॉन का एक पठन जो अगले मिलीसेकंद में सैली में बदलता है, वह पुराना डेटा है। सैली का एक पठन जो जॉन को वापस ले जाता है, अगली मिलीसेकंद पुरानी डेटा है। यह मिलीसेकंद स्तर पर है। मेरे पास एक डेटलोडर है जो उपयोगकर्ताओं को साझा लॉक ले रहा है और चलाने के लिए 4 घंटे चलने में 20 घंटे लगते हैं, उपयोगकर्ता उपयोगकर्ता लॉक नहीं ले रहे हैं। इस मामले में साझा ताले डेटा को 16 घंटे के बालों का कारण बनते हैं।

नोलॉक्स गलत का उपयोग न करें। लेकिन उनके पास एक जगह है। यदि आप एक चेक को काटने जा रहे हैं जब एक बाइट 1 पर सेट किया गया है और फिर चेक को काटते समय इसे 2 पर सेट करें - नोलॉक के लिए समय नहीं।

+1

धन्यवाद। हम समान प्रदर्शन विशेषताओं को देखते हैं। अगर हमें पढ़ने के लिए ताले की आवश्यकता होती है तो हमारी साइट नहीं चलेगी, और ज्यादातर मामलों में इसे रखने का असर केवल महत्वहीन नहीं है। –

+0

@BrianWhite धन्यवाद। किसी को यह मिल जाता है। और मैं अद्यतन और सम्मिलित करने पर बहुत सारे टेबल ताले लेता हूं। अंदर जाओ, इसे पूरा करें, और बाहर निकलें मेरा दृष्टिकोण है। – Paparazzi

+1

गंदा पढ़ा (नोलॉक) बस गंदे लगता है। आपको कभी भी आंशिक डेटा नहीं मिल रहा है। यदि कोई अपडेट जॉन को सैली में बदल रहा है तो आप कभी भी जॉली नहीं ले पाएंगे। - हमने जॉन को सही पढ़ा? – MonsterMMORPG

2

SELECT WITH (NOLOCK) असामान्य डेटा के पढ़ने की अनुमति देता है, जो आपके डेटाबेस पर READ UNCOMMITTED अलगाव स्तर सेट करने के बराबर है। NOLOCK कीवर्ड पूरे डेटाबेस पर अलगाव स्तर स्थापित करने से बेहतर अनाज नियंत्रण की अनुमति देता है।Wikipedia: Isolation (database systems)

यह भी अन्य stackoverflow लेख में विस्तार से चर्चा की है:

विकिपीडिया एक उपयोगी लेख है।

+0

धन्यवाद rghome प्राप्त करने के लिए थोड़ी देर के लिए अपडेट करने जा रहा है। –

+0

यही कारण है कि मैं 'READUNCOMMITTED' (' NOLOCK' के लिए उपनाम) का उपयोग करना पसंद करता हूं, * जब * यह एक वैध उपयोग-मामला है। ऐसा करने से वास्तविक ऑपरेशन होता है, जो * वास्तव में "ताले के बिना" नहीं है, कम अस्पष्ट है। – user2864740

7

मुझे एक महत्वपूर्ण टिप्पणी जोड़नी है। हर कोई उल्लेख कर रहा है कि NOLOCK केवल गंदा डेटा पढ़ता है। यह सटीक नहीं है। यह भी संभव है कि आपको दो बार एक ही पंक्ति मिल जाएगी या आपकी पढ़ के दौरान पूरी पंक्ति छोड़ी जाएगी। कारण यह है कि आप एक ही समय में कुछ डेटा मांग सकते हैं जब SQL सर्वर बी-पेड़ को फिर से संतुलित कर रहा है।

चेक एक और धागे

https://stackoverflow.com/a/5469238/2108874

http://www.sqlmag.com/article/sql-server/quaere-verum-clustered-index-scans-part-iii.aspx)

NOLOCK संकेत के साथ

(या सत्र के अलगाव स्तर की स्थापना अप्रतिबद्ध पढ़ने के लिए) आप एसक्यूएल सर्वर है कि तुम नहीं बता स्थिरता की उम्मीद है, इसलिए कोई गारंटी नहीं है। ध्यान रखें कि "असंगत डेटा" का मतलब यह नहीं है कि आप असामान्य परिवर्तन देख सकते हैं जिन्हें बाद में वापस ले जाया गया था, या लेनदेन के मध्यवर्ती राज्य में डेटा परिवर्तन। इसका यह भी अर्थ है कि एक साधारण क्वेरी में जो सभी तालिका/अनुक्रमणिका डेटा स्कैन करता है SQL सर्वर स्कैन स्थिति खो सकता है, या आप एक ही पंक्ति को दो बार प्राप्त कर सकते हैं।