उत्पादन तालिकाओं में कॉलम जोड़ना


28

SQL Server 2008 R2 पर बड़े उत्पादन तालिकाओं में कॉलम जोड़ने का सबसे अच्छा तरीका क्या है? Microsoft की पुस्तकों के अनुसार ऑनलाइन:

ALTER TABLE में निर्दिष्ट परिवर्तन तुरंत लागू हो जाते हैं। यदि परिवर्तनों को तालिका में पंक्तियों के संशोधनों की आवश्यकता होती है, तो ALTER TABLE पंक्तियों को अपडेट करती है। अन्य तालिका में तालिका के लिए एक स्कीमा संशोधित लॉक प्राप्त होता है जो यह सुनिश्चित करने के लिए होता है कि परिवर्तन के दौरान तालिका के लिए कोई अन्य कनेक्शन संदर्भ मेटाडेटा भी नहीं है, सिवाय ऑनलाइन इंडेक्स ऑपरेशंस के जिन्हें अंत में बहुत ही कम SCH-M लॉक की आवश्यकता होती है।

(Http://msdn.microsoft.com/en-us/library/ms190273.aspx)

लाखों पंक्तियों वाली एक बड़ी मेज पर, इसमें कुछ समय लग सकता है। क्या केवल एक विकल्प के लिए आउटेज लेना है? इस तरह की स्थिति से निपटने का सबसे अच्छा तरीका क्या है?


1
इस समस्या के बारे में हाल के लेख: sqlservercentral.com/articles/Change+Tracking/74397
8kb

जवाबों:


27

"निर्भर करता है"

यदि आप एक कॉलम जोड़ते हैं जिसमें पंक्तियों में डेटा जोड़ने की आवश्यकता नहीं होती है, तो यह काफी जल्दी हो सकता है।

उदाहरण के लिए, एक इंट या चार को जोड़ने से शारीरिक पंक्ति आंदोलनों की आवश्यकता होती है। बिना किसी डिफ़ॉल्ट के अशक्त चरचर जोड़ना (जब तक NULL बिटमैप को विस्तारित करने की आवश्यकता न हो)

आपको अनुमान लगाने के लिए उत्पादन की एक पुनर्स्थापित प्रतिलिपि पर इसे आज़माने की आवश्यकता है

यदि आपको एक बिलियन रो टेबल पर अनुक्रमित और कुंजियों को फिर से जोड़ना है तो एक नई तालिका बनाना, कॉपी करना, नाम बदलना अधिक समय ले सकता है।

मैंने अरब पंक्ति तालिकाओं को बदल दिया है जो एक अशक्त स्तंभ को जोड़ने के लिए कुछ सेकंड लेती हैं।

क्या मैंने पहले बैकअप लेने के लिए कहा था?


2
बैकअप पर +1। और सुनिश्चित करें कि आपके पास पर्याप्त लॉग स्पेस भी है।
स्क्लैकिड

क्या आप स्पष्ट कर सकते हैं कि इंट या चार को जोड़ने के लिए भौतिक पंक्ति आंदोलनों की आवश्यकता क्यों है?
श्यू-बीटा

5
क्या आपका मतलब था "अपनी दूसरी पंक्ति में पंक्तियों में डेटा जोड़ने की आवश्यकता नहीं है"?
बेन ब्रोका

21

यदि स्तंभ NULLable है, तो प्रभाव नगण्य होना चाहिए। यदि स्तंभ NULL नहीं हो सकता है और मान सेट किया जाना चाहिए, तो यह काफी भिन्न हो सकता है। इस मामले में मैं क्या करूँगा, बजाय एक शॉट में एक अशक्त और डिफ़ॉल्ट बाधा जोड़ने के बजाय, प्रभावी ढंग से हर नंबर पर डेटा जोड़ना:

  • कॉलम को NULLable के रूप में जोड़ें - ज्यादातर मामलों में त्वरित होना चाहिए
  • डिफ़ॉल्ट पर मानों को अपडेट करें
    • यदि आवश्यक हो तो आप इसे बैचों में कर सकते हैं
    • आप इसका उपयोग सशर्त तर्क को लागू करने के लिए भी कर सकते हैं जहां कुछ पंक्तियों को डिफ़ॉल्ट नहीं मिल सकता है
  • शून्य / डिफ़ॉल्ट बाधाओं को न जोड़ें
    • यह तब तेज़ होगा जब कोई भी डेटा NULL न हो, लेकिन फिर भी मापने योग्य होना चाहिए

@ के साथ सहमत हैं कि आप उत्पादन की एक प्रति को पुनर्स्थापित करके और इसे वहां आज़माकर इसका परीक्षण कर सकते हैं ... आपको समय का एक अच्छा विचार मिलेगा (हार्डवेयर कुछ इसी तरह का है) और आप लेनदेन लॉग पर भी प्रभाव देख सकते हैं।


अंतिम बिट: •add the not null/default constraintsमुझे यकीन नहीं है कि इसके साथ कोई संभावित समस्या नहीं है ... जब MSSQL (यहां तक ​​कि 2008R2) एक शून्य स्तंभ को शून्य करने के लिए नहीं बदलता है, यदि आप एक ट्रेस डालते हैं तो आप इसे कवर के नीचे देख सकते हैं। तालिका की प्रत्येक पंक्ति का पूर्ण अद्यतन करना, अर्थात update table1 set column1 = column1मुझे लगता है कि यह पूरी तरह से मूर्खतापूर्ण तरीके से नहीं-शून्य सत्यापन कर रहा है। यह लेन-देन तालिका का आकार (पृष्ठों से पहले और बाद में) से दोगुना है, इसलिए DW तालिका के लिए यह बहुत बड़ा हो सकता है। इससे पहले हमें डेटा को bcp करना है, छोटा करना है, गैर-अशक्त परिवर्तन को कम करना है, फिर

अगर किसी को इसके चारों ओर एक रास्ता पता है, मुझे पता है कि प्यार करता हूं ... इसके विपरीत, ओरेकल में, नल को नहीं बदलने के लिए नल को लॉक करता है, फिर कोई गैर नल को सत्यापित करने का चयन करता है, फिर एक तात्कालिक शुद्ध रूप से मेटा डेटा अपडेट।

अरे @ मायके, यह अपने आप में एक अच्छा संभावित प्रश्न लगता है।
डेरेक डाउनी

4

क्या तुमने विचार किया है:

  1. एक नई तालिका बनाना जिसमें तालिका परिभाषा में परिवर्तन शामिल हैं।
  2. मूल तालिका से चयन करते हुए नई तालिका परिभाषा में सम्मिलित करना।
  3. मूल तालिका का नाम बदलकर _orig और फिर नई तालिका का नाम बदलकर मूल तालिका नाम रख दिया गया।

यहां नुकसान यह है कि इस बदलाव को करने के लिए आपके पास डेटाबेस में पर्याप्त जगह होनी चाहिए। किसी भी गंदे रीड को रोकने के लिए आपको टेबल पर एक रीड लॉक की आवश्यकता हो सकती है।

हालाँकि, आप अंतिम उपयोगकर्ताओं को होने वाले प्रभाव को कम कर देते हैं यदि कोई मौका हो या मूल तालिका के समवर्ती रूप से पहुंचने की आवश्यकता हो। यह लॉक अवधि को भी कम से कम करना चाहिए।


क्या आपको पढ़ने के बजाए राइट लॉक की आवश्यकता होगी ? उपयोगकर्ताओं के लिए पुरानी तालिका में डेटा देखना ठीक है, आप बस उन्हें किसी भी बदलाव के लिए नहीं चाहते हैं जब आप बफर स्वैप खत्म कर देंगे।
जॉन ऑफ ऑल ट्रेड्स

यह मेरी डेटा वेयरहाउस टोपी के साथ मेरी सोच थी जहां बदलावों को थोड़ा आसान नियंत्रित किया जा सकता है। OLTP स्थिति में आप सही हैं, तालिका में किए जा रहे परिवर्तनों से बचने के लिए राइट लॉक आवश्यक होगा।
रॉबपेलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.