2012-02-13 9 views
5

La società per cui lavoro ha alcune enormi tabelle di registro/giornale che vengono scritte ogni 10 secondi circa con le transazioni. Vorrei copiare un sacco di dati in questa tabella ed eliminarlo da quella tabella perché circa il 75% dei vecchi dati potrebbe essere messo in una tabella di archivio o qualcosa del genere, ma se faccio questo sbagliato e la tabella viene bloccata sarebbe un disastro.copia dei dati da un'enorme tabella di produzione

In una domanda precedente un tizio si avvicinò con una cosa del genere, mi piacerebbe sapere che questo non rovinerebbe tutto, è l'idea del nolock sufficiente per tenermi al sicuro e tutte le scritture funzionano bene? Se no, cosa dovrei fare?

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

Questo è fantastico eccetto qual è il piano per CANCELLARE i vecchi record? Non è davvero un modo per farlo senza una sorta di blocco. – JNK

+0

Sì, ho chiarito la domanda un po ', quindi qual è il modo migliore per cancellare i vecchi record senza intralciare le normali operazioni db? –

risposta

3

L'estrema cautela nella generazione dell'elenco è probabilmente fuori bordo, ma è consigliabile eseguire un'eliminazione batch.

Per il INSERT, probabilmente non è necessario il ciclo WHILE. Per la DELETE, però, vorrei usare qualcosa di simile (regolare la dimensione dei lotti alle proprie esigenze):

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 

Questo sarà DELETE record 10k alla volta fino a quando non ci sono record da eliminare.

+0

Ho fatto qualcosa di simile in passato con una tabella di grandi dimensioni, archiviando ed eliminando record in batch . Fondamentalmente sembrava il tuo codice ma con un "inizio tran" e un "commit tran" all'interno del ciclo while. Ho quindi eseguito il backup, troncato e ridotto il registro. –

+0

Se è preoccupato per la contesa non farei una transazione in quanto bloccherebbe la tabella :) – JNK

+0

Grazie JNK, quindi consiglieresti di eseguire prima la copia e poi di eliminare? Qualcos'altro di cui ho bisogno di preoccuparmi? Scusa, sono solo un paranoico, ma penso che possa funzionare. –

0

Una possibilità è quella di partizionare il tavolo per ora (ammesso che abbiate una colonna DATETIME nella tabella che il default è GETDATE() su ogni inserto). Avere le partizioni consente di eseguire la manutenzione (rilascio, copia, ecc.) Sulle partizioni precedenti senza influire su quella corrente.

+1

Si preoccupa di bloccare il tavolo abbastanza a lungo da selezionare e si sta suggerendo di aggiungere uno schema di partizione? Sono abbastanza sicuro che causerà anche un po 'di blocco ... – JNK

+0

@JNK sì ma potrebbe essere parte di un futuro downtime pianificato –

Problemi correlati