सभी पंक्तियों को अपडेट करें


12

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

update mytable set mycolumn=null;

या:

update mytable set mycolumn=42;

मेरा ज्ञान बहुत अच्छी तरह से बासी हो सकता है। स्तंभ को छोड़ने के लिए मैं तालिका को बदल रहा हूं। फिर, मैं उस नए मान के डिफ़ॉल्ट मान के साथ कॉलम जोड़ने के लिए तालिका को बदल देता हूं जिसे मैं उपयोग करना चाहता हूं। फिर, मैं स्तंभ के लिए डिफ़ॉल्ट मान को हटाने के लिए तालिका को बदल देता हूं। मुझे लगता है कि यह केवल एक अपडेट चलाने की तुलना में बहुत तेज है, लेकिन मुझे लगता है कि एक बेहतर तरीका है।


जहां तक ​​मैं समझता हूं कि एक डिफ़ॉल्ट के साथ एक नया नहीं अशक्त स्तंभ जोड़ना ओरेकल में मेटाडेटा केवल परिवर्तन है। मुझे संदेह है कि उन्होंने "सभी पंक्तियों को समान मान पर अद्यतन करें" मामले को अनुकूलित किया होगा। क्या यह आपके लिए एक सामान्य ऑपरेशन है?
मार्टिन स्मिथ

1
बस दोनों तरीकों की कोशिश करें और उन्हें समय दें। आपको ऐसा करने से क्या रोक रहा है? इस तथ्य को देखें कि आपको एक ही परिणाम के साथ समाप्त होना चाहिए, अलग परिणाम के साथ नहीं! अन्यथा, तुलना अमान्य है।
TVCa

@tvCa मैंने दोनों तरह से कोशिश की है। अगर मैं सिर्फ एक अपडेट करता हूं, तो यह लगभग दो घंटे चलता है और फिर मैं इसे मार देता हूं। यदि मैं किसी कॉलम को छोड़ता हूं, तो केवल कुछ सेकंड लगते हैं। डिफ़ॉल्ट मान के बिना एक स्तंभ जोड़ना (जो स्तंभ को शून्य करता है) केवल कुछ सेकंड लेता है। डिफ़ॉल्ट मान के साथ एक स्तंभ जोड़ने में लगभग 30 मिनट लगते हैं। इसलिए, यदि मैं उदाहरण के लिए, किसी कॉलम में सभी मानों को 'कुछ मान' पर सेट करना चाहता हूं, तो मैं वर्तमान में कॉलम को छोड़ता हूं और जोड़ता हूं। मैं सिर्फ यह जानना चाहता हूं कि क्या ऐसा करने का कोई तेज तरीका है।
kainaw

2
क्या आप 11gR2 का उपयोग कर रहे हैं? @MartinSmith सही है। नए कॉलम को DEFAULT के साथ जोड़ने के तरीके के विवरण के लिए यहां देखें क्योंकि NULL के रूप में इसे जोड़ने से ज्यादा तेज बदलाव नहीं है, जो तालिका में सभी पंक्तियों के अपडेट को बाध्य करेगा (बस एक अद्यतन विवरण जारी करने के रूप में)। मेरे द्वारा देखी जाने वाली समस्या बाद में DEFAULT मान निकाल रही है, क्योंकि प्रदर्शन में वृद्धि DEFAULT को शब्दकोश में संग्रहीत करने से होती है। आपको उस बिंदु पर NOT NULL बाधा से भी निपटना होगा।
अन्सिबल

जवाबों:


2

जब आप यह बड़े पैमाने पर अपडेट कर रहे होते हैं तो इस तालिका के विरुद्ध चल रही अन्य गतिविधि पर बहुत कुछ निर्भर करता है। मुझे आशा है कि आपके पास कुछ प्रकार का परीक्षण वातावरण है जहां आप जो करना चाहते हैं उसके कुछ नमूने चला सकते हैं और इस बात का अंदाजा लगा सकते हैं कि कौन सा तरीका सबसे अच्छा है। मैं कोशिश करूँगा:

  1. सिंगल को चलाएं update table set column_name = blah;
  2. तालिका में सभी प्राथमिक कुंजी और उनके माध्यम से लूप का चयन करने के लिए एक plSql लूप बनाएं, updating the column=blahऔर हर एक्स अपडेट (शायद 10000) को प्रतिबद्ध करें। आप इस कोड को कॉपी करके और इसे कॉपी करके प्राथमिक कुंजी का एक अलग अनुभाग बना सकते हैं।

हमारे पास तालिका के साथ एक बहुत ही समान मुद्दा था जो ओएलटीपी प्रणाली में बहुत सक्रिय रूप से उपयोग किया गया था और हम इसे 5x समानांतर करने में सक्षम थे और प्रत्येक 10000 पर एक 100+ एमएम पंक्ति तालिका पर कोई उपयोगकर्ता लॉकिंग प्रभाव के साथ नहीं चल रहा था। आपने यह नहीं बताया कि कैसे आपकी तालिका बड़ी है या आपके द्वारा किस प्रकार का अनुप्रयोग चल रहा है, लेकिन इस तरह का समाधान आपको फिट हो सकता है।


0

एक उपवास के लिए UPDATE, सुनिश्चित करें कि आपके पास कोई ट्रिगर नहीं है जो फायरिंग कर रहे हैं।

SELECT trigger_name, status FROM user_triggers WHERE table_name = 'MYTABLE';

ALTER TABLE mytable DISABLE ALL TRIGGERS;

जब आप पूरा कर लें, तो केवल उन्हें पुनः सक्षम करना सुनिश्चित करें।

ALTER TRIGGER mytrigger ENABLE;

आप इंडेक्स मेंटेनेंस के ओवरहेड में भी चल सकते हैं। अपने अनुक्रमणिका को अलग से पुनर्निर्माण करने का प्रयास करें। ऐसा करने के लिए, यहाँ पेप्पों द्वारा उत्तर सहायक होना चाहिए: /programming/129046/disable-and-later-enable-all-table-indexes-in-oracle

मैं संदर्भ के लिए यहां पप्पों के उत्तर को दोहरा रहा हूं। (ध्यान दें कि यह SPOOL कमांड आपके प्लेटफॉर्म और पर्यावरण के बारे में धारणा बनाता है।)

set pagesize 0    
alter session set skip_unusable_indexes = true;
spool c:\temp\disable_indexes.sql
select 'alter index ' || u.index_name || ' unusable;' from user_indexes u;
spool off
@c:\temp\disable_indexes.sql

आयात करें ...

select 'alter index ' || u.index_name || ' rebuild online;'
  from user_indexes u;

-1

सूचकांक निकालें। कॉलम अपडेट करें। सूचकांक वापस करें। लेकिन यदि कॉलम में सभी पंक्तियों के लिए एक और समान मान है तो आप सूचकांक को छोड़ सकते हैं।


-2

यदि आपके पास स्थान सीमा नहीं है, तो आप एक नई तालिका बना सकते हैं, जैसे कि आपके नए स्तंभ के साथ आपकी तालिका उस तालिका में जोड़ दी गई है और पुरानी तालिका हटा दी गई है:

create new_table as
select old_table.*, (with or without default_Value) as new_column
from old_table;

1
क्या यह अधिक कुशल होगा? क्यों? और क्या होगा यदि मौजूदा तालिका को संदर्भित करने वाले एफके हैं?
ypercube y

हाँ, आप इसे अन्य नमूना तालिका पर आज़मा सकते हैं और परिणाम स्वयं देख सकते हैं। यदि एफके हैं, तो मुझे ठीक से पता नहीं है लेकिन आप इसे अक्षम कर सकते हैं और सक्षम कर सकते हैं यदि यह कुशल है।
E_Salamon

-3

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

एक मेज पर पूरे डेटा को हटाने के लिए, truncate table xसे बेहतर है delete from x। इसके अलावा purging एक और प्रक्रिया कार्यभार बनाता है।

संपादित करें: आप inmemoryकॉलम प्रारूप में मेमोरी में विकल्प, लोडिंग टेबल का उपयोग कर सकते हैं और फिर अपडेट कर सकते हैं। यह वास्तव में आपके DB के संबंधों और संरचना पर निर्भर करता है। इस लेख को देखें


3
वे तालिका के एक कॉलम को अपडेट करना चाहते हैं। मैं नहीं देखता कि कैसे truncateया deleteकिसी भी मदद का होगा।
ypercube y

@ypercube मैंने अभी समझाया कि बिना कमिटमेंट के कितने डेटा हेरफेर से अवांछित IO लोड होता है; या तो अपडेट हो या अन्य ओएलटीपी एस।
चालाक

3
क्या आप बता सकते हैं कि I / O कम होने पर कितनी बार कम होता है ? क्या वे चौकियों के कारण I / O नहीं बढ़ाएंगे ?
मस्टीको

3
गैर-पारंपरिक शब्दावली ("tx जर्नल", "आपका सत्र फ्लश करता है") का आपका उपयोग थोड़ा भ्रमित करने वाला है। चाहे आप कई छोटे लेनदेन या एक बड़े पैमाने पर लेनदेन का उपयोग करते हैं, उत्पन्न रीडो रिकॉर्ड की कुल मात्रा समान होगी। I / O संचालन केवल तब होता है जब रीडो लॉग बफर डिस्क के लिए लिखा जाता है (अब के लिए अकेले बफर कैश चौकियों को छोड़कर), जो प्रतिबद्ध होने पर या फिर जब Redo बफर लगभग पूर्ण होता है। इसके बाद, यदि आप बार-बार करते हैं तो आप अतिरिक्त I / O का कारण बनते हैं, इसलिए मैं सोच रहा हूं कि मैं / O कैसे कम कर सकता हूं।
मस्टीको

4
आप क्या टॉम Kyte के बारे में "बार-बार करता" क्या कहना है पढ़ने के लिए चाहते हो सकता है: asktom.oracle.com/pls/apex/... " गलत, गलत, गलत है तो गलत .... तो बहुत बहुत गलत। "
a_horse_with_no_name
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.