किसी तालिका में बड़े परिवर्तन के लिए बेहतर क्या है: DELETE और INSERT हर बार या मौजूदा अद्यतन करें?


27

मैं एक ऐसी परियोजना बना रहा हूँ जहाँ मुझे प्रतिदिन एक तालिका में लगभग 36K रिकॉर्ड बदलने की आवश्यकता है। मैं सोच रहा हूँ कि क्या बेहतर प्रदर्शन करेंगे:

  1. पंक्तियों को हटाएं और नए डालें, या
  2. पहले से मौजूद पंक्तियों को अपडेट करें

मेरे लिए केवल सभी पंक्तियों को हटाना और नए को सम्मिलित करना आसान है, लेकिन अगर यह तालिका और अनुक्रमणिका को प्रभावित करने और प्रदर्शन को प्रभावित करने वाला है तो मैं जहां संभव हो अपडेट करना और केवल आवश्यक होने पर हटाना / सम्मिलित करना पसंद करूंगा।

यह एक रात्रिकालीन सेवा है और मैं इस प्रक्रिया की गति में सुधार नहीं कर रहा हूं। मैं सामान्य रूप से इस तालिका के खिलाफ प्रश्नों के प्रदर्शन के बारे में अधिक चिंतित हूं जहां मेरे पास पहले से ही 89 मिलियन रिकॉर्ड हैं और यह रात्रिकालीन प्रक्रिया को कैसे प्रभावित करेगा।

क्या मुझे इस रात की प्रक्रिया के लिए रिकॉर्ड्स को हटाना / सम्मिलित करना चाहिए या क्या मुझे मौजूदा (जहां संभव हो) अपडेट करना चाहिए?


मेरा मानना ​​है कि आपको अपनी मेज पर अधिक विवरण देना चाहिए, क्योंकि मुझे लगता है कि यह खेतों पर सूचकांकों के संभावित अस्तित्व पर निर्भर करेगा।
एसआरकेएक्स

जवाबों:


9

यह वास्तव में इस बात पर निर्भर करता है कि डेटा कितना बदल रहा है। बता दें कि इस टेबल में 20 कॉलम हैं। और आपके पास 5 इंडेक्स भी हैं - प्रत्येक एक अंतर पर। स्तंभ।

अब यदि सभी 20 कॉलमों में मान बदल रहे हैं या भले ही 5 कॉलमों में डेटा बदल रहे हैं और ये 5 कॉलम सभी अनुक्रमित हैं, तो आप "हटाना और सम्मिलित करना" से बेहतर हो सकते हैं। लेकिन अगर केवल 2 कॉलम बदल रहे हैं और कह सकते हैं कि ये किसी भी गैर-क्लस्टर इंडेक्स का हिस्सा नहीं हैं, तो आप रिकॉर्ड को "अपडेट" करना बेहतर हो सकते हैं क्योंकि इस मामले में केवल क्लस्टर इंडेक्स अपडेट किया जाएगा (और इंडेक्स नहीं होंगे) अद्यतन किया जा)।


आगे के शोध पर, मैंने पाया कि मेरे द्वारा की गई उपरोक्त टिप्पणी बेमानी है, क्योंकि SQL सर्वर आंतरिक रूप से 2 अलग तंत्र के लिए UPDATE करता है। - एक "इन-प्लेस अपडेट" (यानी मूल पंक्ति में एक कॉलम के मूल्य को नए में बदलकर) या "इन-प्लेस UPDATE" के रूप में (DELETE के बाद INSERT)।

स्थान अपडेट में नियम हैं और यदि संभव हो तो प्रदर्शन किया जाता है। यहाँ पंक्तियाँ एक ही पृष्ठ पर एक ही स्थान पर एक ही स्थान पर बिल्कुल रहती हैं। केवल प्रभावित बाइट्स chnaged हैं। टॉगल में केवल एक रिकॉर्ड होता है (बशर्ते कोई अपडेट ट्रिगर न हो)। अपडेट जगह में होते हैं यदि एक ढेर अद्यतन किया जा रहा है (और पृष्ठ पर पर्याप्त जगह है)। क्लस्टरिंग कुंजी में परिवर्तन होने पर भी अपडेट होते रहते हैं लेकिन पंक्ति को बिल्कुल भी स्थानांतरित करने की आवश्यकता नहीं होती है।

उदाहरण के लिए: यदि आपके पास अंतिम नाम पर एक क्लस्टर इंडेक्स है और आपके नाम हैं: एबल, बेकर, चार्ली अब आप बेकर को बेकर को अपडेट करना चाहते हैं। कोई पंक्तियों को स्थानांतरित नहीं करना है। तो यह जगह ले सकता है। जबकि, यदि आपको Able to Kumar को अपडेट करना है, तो पंक्तियों को स्थानांतरित करना होगा (भले ही वे उसी पृष्ठ पर होंगे)। इस स्थिति में, SQL सर्वर एक DELETE करेगा जिसके बाद एक INSERT होगा।

उपरोक्त को ध्यान में रखते हुए, मैं आपको सुझाव दूंगा कि आप एक सामान्य अद्यतन करें और आंतरिक रूप से कैसे करें के लिए SQL सर्वर को सबसे अच्छा तरीका बताएं।

"UPDATE" इंटर्नल्स के बारे में अधिक जानकारी के लिए या उस SQL ​​सर्वर से संबंधित किसी भी मामले के लिए, Kalen Delaney, Paul Randal's, et al.'s book - SQL Server 2008 Internals देखें


8

क्या आपने SQL 2008 में MERGE कमांड की जांच की है ? यहाँ एक बुनियादी उदाहरण है:

  merge YourBigTable ybt
  using (select distinct (RecordID) from YourOtherTable) yot
     on yot.Recordid = YBT.RecordID
  when NOT matched by target
  then  insert (RecordID)
        values (yot.DeviceID) ;

यह मूल रूप से एक "यूपीएसईआरटी" कमांड है। यदि यह मौजूद है तो अपडेट करें, अगर यह नहीं है तो इसे डालें। बहुत तेज, बहुत अच्छा आदेश।


1
यह एक अद्यतन से तेज नहीं है, हुड के नीचे एक ही यांत्रिकी।
मार्क स्टोरी-स्मिथ

यह अद्यतन करने की तुलना में तेज़ है और पहले से मौजूद नहीं हैं।
डेटागोड

2
यदि आप जानते हैं कि यह मामला है, तो इसे साबित करें :)
मार्क स्टोरी-स्मिथ

4

लेकिन, मैंने खुद एक ऐसे टेबल पर डिलीट और इन्सर्ट बनाम अपडेट को चेक किया, जिसमें 30million (3crore) रिकॉर्ड हैं। इस तालिका में एक अद्वितीय कंपोज़िट कुंजी और 3 नॉनक्लेस्टेड कीज़ हैं। Delete & Insert के लिए, इसमें 9 मिनट लगते हैं। अपडेट के लिए इसमें 55 मिनट का समय लगा। केवल एक कॉलम है जिसे प्रत्येक पंक्ति में अपडेट किया गया था।

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


मैंने इस मामले को भी मारा है, लेकिन फिर पता चला कि कभी-कभी स्रोत या लक्ष्य, संकेत या लक्ष्य को उप-सेटिंग (पूर्ण मर्ज के लिए लागू नहीं) को जोड़कर बड़े मर्ज को अनुकूलित करना संभव है।
क्रुकसेक

3

अपडेट उतना तेज नहीं है। डेटा डालने के दौरान अनुक्रमणिका को अक्षम करने के लिए एक तेज़ सम्मिलित करने के लिए चाल है।

इसका उपयोग करने पर विचार करें:

-- disable indexes
ALTER INDEX [index_name] ON dbo.import_table DISABLE
-- ... disable more indexes

-- don't use delete if you don't care about minimal logging. truncate is faster
TRUNCATE TABLE dbo.import_table

-- just insert the new rows
INSERT dbo.import_table
SELECT
    *
FROM
    dbo.source_table

-- rebuild indexes
ALTER INDEX [index_name] ON dbo.import_table REBUILD
-- ... rebuild more indexes

यहां तक ​​कि तेजी से db विकल्पों में स्वत: सांख्यिकी अपडेट को भी बंद करना है। यदि तालिका महत्वपूर्ण रूप से बदली गई है तो आपको चलना चाहिए:

UPDATE STATISTICS dbo.import_table

या

EXEC sp_updatestats

आँकड़ों को बनाए रखने के लिए एक नियमित आधार पर नौकरी के रूप में (दैनिक आकार के आधार पर दैनिक, साप्ताहिक)। तालिका खाली होने पर आंकड़ों को अपडेट करना है। यदि आप तालिका को फिर से आबाद करने के बाद इसे नहीं चलाते हैं, तो यह आंकड़े को खराब कर देगा।


4
मैं असहमत हूं कि हमेशा ऐसा ही होता है। इसके अलावा, @ गोद लेने के प्रश्न में तालिका TRUNCATE द्वारा साफ़ नहीं की जा सकती क्योंकि इसमें 89m रिकॉर्ड हैं और वह केवल 36k को अपडेट करना चाहता है।
मार्क स्टोरी-स्मिथ

पोस्ट को और अधिक सावधानी से पढ़ना सीखना होगा! मैं पोस्ट को अपडेट करूंगा ... वास्तव में, मुझे बहुत कुछ बदलने की आवश्यकता है।
आस्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.