मेरे दृष्टिकोण से आपके सर्वर में गंभीर प्रदर्शन समस्या है। भले ही हम मान लें कि क्वेरी में कोई भी रिकॉर्ड नहीं है
select some_col with (nolock) where id_col between 57000000 and 57001000
स्मृति में था, डिस्क से क्रमिक रूप से कुछ पृष्ठों को पढ़ने में 21 सेकंड का समय नहीं लगना चाहिए (यदि id_col पर आपका क्लस्टर इंडेक्स खंडित नहीं होना चाहिए यदि यह एक ऑटो-पहचान है और आपने "desc" जोड़ने जैसा कुछ बेवकूफी भरा नहीं किया है सूचकांक परिभाषा के लिए)।
लेकिन अगर आप इसे ठीक नहीं कर सकते/नहीं कर सकते हैं, तो मेरी सलाह होगी कि एक बार में 100-1000 रिकॉर्ड जैसे छोटे पैकेजों में अपडेट करें (लुकअप फ़ंक्शन कितना समय लेता है इस पर निर्भर करता है)। एक अपडेट/लेनदेन में 30 सेकंड से अधिक समय नहीं लगना चाहिए।
आप देखते हैं कि प्रत्येक अद्यतन लेन-देन पूरा होने तक संशोधित किए गए सभी रिकॉर्ड पर एक विशेष लॉक रखता है। यदि आप स्पष्ट लेन-देन का उपयोग नहीं करते हैं, तो प्रत्येक कथन को एकल, स्वचालित लेन-देन के संदर्भ में निष्पादित किया जाता है, इसलिए अद्यतन विवरण पूरा होने पर ताले जारी हो जाते हैं।
लेकिन आप अभी भी इस तरह से गतिरोध में भाग सकते हैं, यह इस बात पर निर्भर करता है कि अन्य प्रक्रियाएं क्या करती हैं। यदि वे एक समय में एक से अधिक रिकॉर्ड को भी संशोधित करते हैं, या भले ही वे कई पंक्तियों में रीड लॉक को इकट्ठा करके रखते हैं, तो आप गतिरोध प्राप्त कर सकते हैं।
गतिरोध से बचने के लिए, आपके अपडेट स्टेटमेंट को उन सभी रिकॉर्ड्स पर रोक लगाने की जरूरत है, जिन्हें वह एक ही बार में संशोधित करेगा। ऐसा करने का तरीका यह है कि एकल अद्यतन विवरण (id_col द्वारा सीमित केवल कुछ पंक्तियों के साथ) को क्रमबद्ध लेनदेन में रखा जाए जैसे
IF @@TRANCOUNT > 0
-- Error: You are in a transaction context already
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
-- Insert Loop here to work "x" through the id range
BEGIN TRANSACTION
UPDATE SOMETABLE
SET [some_col] = dbo.ufn_SomeFunction(CONVERT(NVARCHAR(500), another_column))
WHERE [some_col] = 243 AND id_col BETWEEN x AND x+500 -- or whatever keeps the update in the small timerange
COMMIT
-- Next loop
-- Get all new records while you where running the loop. If these are too many you may have to paginate this also:
BEGIN TRANSACTION
UPDATE SOMETABLE
SET [some_col] = dbo.ufn_SomeFunction(CONVERT(NVARCHAR(500), another_column))
WHERE [some_col] = 243 AND id_col >= x
COMMIT
प्रत्येक अपडेट के लिए यह दिए गए रिकॉर्ड पर एक अपडेट/अनन्य की-रेंज लॉक लेगा (लेकिन केवल उन्हें, क्योंकि आप क्लस्टर इंडेक्स कुंजी के माध्यम से अपडेट को सीमित करते हैं)। यह उसी रिकॉर्ड पर किसी भी अन्य अपडेट के समाप्त होने की प्रतीक्षा करेगा, फिर इसे लॉक कर देगा (अन्य सभी लेनदेन के लिए अवरुद्ध कर रहा है, लेकिन फिर भी केवल दिए गए रिकॉर्ड के लिए), फिर रिकॉर्ड अपडेट करें और लॉक जारी करें।
अंतिम अतिरिक्त विवरण महत्वपूर्ण है, क्योंकि यह "अनंत" तक एक कुंजी श्रेणी लॉक करेगा और इस प्रकार अद्यतन विवरण चलने के दौरान सीमा के अंत में भी सम्मिलित होने से रोकेगा।