2012-02-13 4 views
5

जिस कंपनी के लिए मैं काम कर रहा हूं उसके पास कुछ विशाल लॉग/जर्नल टेबल हैं जो लेनदेन के साथ हर 10 सेकंड या उससे भी अधिक समय में लिखी जा रही हैं। मैं इस तालिका में बहुत सारे डेटा को कॉपी करना चाहता हूं और उसे उस तालिका से हटा देना चाहता हूं क्योंकि लगभग 75% पुराने डेटा को संग्रह तालिका या कुछ में रखा जा सकता है, लेकिन यदि मैं यह गलत करता हूं और तालिका लॉक हो जाती है यह एक आपदा होगी।एक विशाल उत्पादन तालिका से डेटा कॉपी करना

पिछले प्रश्न में एक लड़का इस तरह से कुछ आया, मैं जानना चाहता हूं कि यह सबकुछ खराब नहीं करेगा, क्या मुझे सुरक्षित रखने के लिए पर्याप्त नोलॉक संकेत है और सभी लिखने ठीक काम कर रहे हैं? यदि नहीं, तो मुझे क्या करना चाहिए? (यह मानते हुए आप तालिका में एक DATETIME स्तंभ है कि हर डालने पर GETDATE() करने के लिए डिफ़ॉल्ट है)

set identity_insert newtable on 
DECLARE @StartID bigint, @LastID bigint, @EndID bigint 
select @StartID = max(id)+1 
from newtable 

select @LastID = max(ID) 
from oldtable 

while @StartID < @LastID 
begin 
set @EndID = @StartID + 1000000 

insert into newtable (FIELDS,GO,HERE) 
select FIELDS,GO,HERE from oldtable (NOLOCK) 
where id BETWEEN @StartID AND @EndId 

set @StartID = @EndID + 1 
end 
set identity_insert newtable off 
go 
+1

पुराने रिकॉर्ड को हटाने के लिए आपकी योजना क्या है इसके अलावा यह बहुत अच्छा है? ऐसा करने का कोई तरीका नहीं है कि बिना किसी प्रकार के लॉकिंग हो। – JNK

+0

हाँ, मैंने सवाल को थोड़ा सा स्पष्ट किया है, तो सामान्य डीबी संचालन के रास्ते में नहीं पहुंचते समय पुराने रिकॉर्ड को हटाने का सबसे अच्छा तरीका क्या है? –

उत्तर

3

आपकी सूची बनाने में अत्यधिक सावधानी शायद ओवरबोर्ड है, लेकिन आप बैच डिलीट को चलाने के लिए चाहते हैं।

INSERT के लिए, आपको शायद WHILE लूप की आवश्यकता नहीं है। DELETE के लिए, हालांकि, मैं कुछ इस तरह (धुन अपनी आवश्यकताओं के बैच का आकार) का प्रयोग करेंगे:

WHILE 1=1 
BEGIN 
    DELETE TOP (10000) o 
    FROM OldTable o 
    INNER JOIN NewTable N 
     ON o.id = n.id 
    IF @@ROWCOUNT < 10000 BREAK; 
END 

यह होगा एक समय में DELETE 10k रिकॉर्ड रूप में लंबे समय के रूप में वहाँ से हटाने के लिए रिकॉर्ड कर रहे हैं।

+0

मैंने अतीत में कुछ बड़ी चीजों के साथ ऐसा किया है, बैच में रिकॉर्ड संग्रहित करना और हटाना । असल में यह आपके कोड की तरह दिखता था लेकिन थोड़ी देर के अंदर "प्रारंभ ट्रैन" और "प्रतिबद्ध ट्रैन" के साथ। मैंने फिर बैक-अप, कटा हुआ और लॉग को संकुचित कर दिया। –

+0

यदि वह विवाद के बारे में चिंतित है तो मैं लेनदेन नहीं करूँगा क्योंकि वह तालिका को लॉक करेगा :) – JNK

+0

धन्यवाद जेएनके, तो आप अनुशंसा करेंगे कि मैं पहले प्रतिलिपि करता हूं तो हटाएं? मुझे और चिंता करने की ज़रूरत है? क्षमा करें, मैं सिर्फ सुपर पागल हूं, लेकिन मुझे लगता है कि ऐसा लगता है जैसे यह काम करेगा। –

0

एक विकल्प घंटे के हिसाब से तालिका विभाजन है। विभाजन होने से आप मौजूदा विभाजन को प्रभावित किए बिना पुराने विभाजन पर रखरखाव (ड्रॉप, प्रतिलिपि, आदि) निष्पादित कर सकते हैं।

+1

वह लंबे समय तक तालिका को लॉक करने के बारे में चिंतित है और आप विभाजन योजना जोड़ने का सुझाव दे रहे हैं? मुझे पूरा यकीन है कि कुछ लॉकिंग भी हो जाएगा ... – JNK

+0

@ जेएनके हाँ, लेकिन यह भविष्य की योजनाबद्ध डाउनटाइम का हिस्सा हो सकता है –