2012-02-13 8 views
5

Firma, dla której pracuję, ma kilka ogromnych tabel dziennika/dziennika, które są zapisywane co 10 sekund przy transakcjach. Chciałbym skopiować wiele danych z tej tabeli i usunąć ją z tej tabeli, ponieważ około 75% starych danych można umieścić w tabeli archiwum lub coś podobnego, ale jeśli zrobię to źle, a tabela zostanie zablokowana to byłaby katastrofa.kopiowanie danych z ogromnego stołu produkcyjnego

W poprzednim pytaniu facet wymyślił coś takiego, chciałbym wiedzieć, że to nie wszystko zepsuje, czy wskazówka nolock wystarczy, aby zachować bezpieczeństwo, a wszystkie pisma działają dobrze? Jeśli nie, co powinienem zrobić?

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

To jest świetne, z wyjątkiem tego, jaki jest twój plan usuwania starych zapisów? Naprawdę nie jest to możliwe bez jakiegoś blokowania. – JNK

+0

Tak, trochę wyjaśniłem pytanie, więc jaki jest najlepszy sposób na usunięcie starych rekordów, a jednocześnie nie przeszkadza w normalnych operacjach db? –

Odpowiedz

3

Nadzwyczajna ostrożność podczas generowania listy jest prawdopodobnie za burtą, ale konieczne będzie uruchomienie usuwania partii.

Dla INSERT prawdopodobnie nie potrzebujesz pętli WHILE. Dla DELETE, choć chciałbym użyć czegoś takiego (dostosować wielkość partii do swoich potrzeb):

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 

To będzie DELETE rekordy 10k naraz tak długo jak istnieją rekordy do usunięcia.

+0

Zrobiłem coś podobnego w przeszłości z dużym stołem, archiwizując i usuwając rekordy w partiach . Zasadniczo wyglądało to jak twój kod, ale z "begin tran" i "commit tran" wewnątrz pętli while. Następnie zapisałem, skróciłem i skurczyłem dziennik. –

+0

Jeśli martwi się o rywalizację, nie zrobiłbym transakcji, ponieważ zablokowałoby to stół :) – JNK

+0

Dziękuję JNK, więc poleciłbym najpierw zrobić kopię, a następnie usunąć? Coś, o co muszę się martwić? Przepraszam, jestem po prostu super paranoikiem, ale wydaje mi się, że to zadziała. –

0

Jedną z opcji jest, aby podzielić tabelę na godzinę (zakładając, że masz kolumnę w tabeli DATETIME że domyślnie GETDATE() na każdej wkładce). Posiadanie partycji umożliwia wykonywanie czynności konserwacyjnych (upuszczanie, kopiowanie itd.) Na starszych partycjach bez wpływu na bieżące.

+1

Jest zaniepokojony zablokowaniem stołu wystarczająco długo, aby wybrać i sugerujesz dodanie schematu partycji? Jestem pewien, że spowoduje to również blokowanie ... – JNK

+0

@JNK tak, ale to może być część przyszłego zaplanowanego przestoju –

Powiązane problemy