Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

MS SQL की पृष्ठभूमि में बड़े प्रश्नों को चलाना

मेरे दृष्टिकोण से आपके सर्वर में गंभीर प्रदर्शन समस्या है। भले ही हम मान लें कि क्वेरी में कोई भी रिकॉर्ड नहीं है

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

प्रत्येक अपडेट के लिए यह दिए गए रिकॉर्ड पर एक अपडेट/अनन्य की-रेंज लॉक लेगा (लेकिन केवल उन्हें, क्योंकि आप क्लस्टर इंडेक्स कुंजी के माध्यम से अपडेट को सीमित करते हैं)। यह उसी रिकॉर्ड पर किसी भी अन्य अपडेट के समाप्त होने की प्रतीक्षा करेगा, फिर इसे लॉक कर देगा (अन्य सभी लेनदेन के लिए अवरुद्ध कर रहा है, लेकिन फिर भी केवल दिए गए रिकॉर्ड के लिए), फिर रिकॉर्ड अपडेट करें और लॉक जारी करें।

अंतिम अतिरिक्त विवरण महत्वपूर्ण है, क्योंकि यह "अनंत" तक एक कुंजी श्रेणी लॉक करेगा और इस प्रकार अद्यतन विवरण चलने के दौरान सीमा के अंत में भी सम्मिलित होने से रोकेगा।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. आसान तरीका किसी दी गई तालिका के लिए प्राथमिक कुंजी के रूप में सही कॉलम का चयन करें

  2. मैं SQL सर्वर में बिगिंट (यूनिक्स टाइमस्टैम्प) को डेटाटाइम में कैसे परिवर्तित कर सकता हूं?

  3. एसक्यूएल सर्वर (टी-एसक्यूएल) में संयोजन कैसे खोजें

  4. तालिका-मूल्यवान फ़ंक्शन को कॉल करते समय एक क्वेरी संकेत जोड़ना

  5. रिकॉर्ड अपडेट करने के लिए कर्सर का उपयोग कैसे करें