2012-02-13 51 views
5

我正在使用的公司有一些大型的日誌/日記表,這些日誌表正在使用事務每10秒鐘寫入一次。我想複製這個表中的大量數據,並從表中刪除它,因爲大約75%的舊數據可以放在一個存檔表或其他東西中,但是如果我做錯了,表被鎖定這將是一場災難。將數據從大型生產表中複製出來

在上一個問題中,一個人想出了類似的東西,我想知道這不會把所有東西搞砸,nolock的提示足以保證我的安全,所有的寫入工作都很好嗎?如果不是,我該怎麼辦?

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 2012-02-13 21:04:04

+0

是的,我稍微澄清了這個問題,那麼在不妨礙正常數據庫操作的情況下刪除舊記錄的最佳方法是什麼? – 2012-02-13 21:11:00

回答

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

我在過去曾經做過類似的大表,分批歸檔和刪除記錄。基本上它看起來像你的代碼,但在while循環中有一個「begin tran」和一個「commit tran」。然後我做了備份,截斷並縮小了日誌。 – 2012-02-13 21:21:52

+0

如果他擔心爭用,我不會做交易,因爲這會鎖定表:) – JNK 2012-02-13 21:25:19

+0

感謝JNK,所以你會建議我先複製然後做刪除?還有什麼我需要擔心的?對不起,我只是超級偏執狂,但我認爲這似乎是行得通的。 – 2012-02-13 21:27:38

0

一種選擇是按小時對錶進行分區(假設你在表中的列DATETIME默認爲GETDATE()每個插入)。擁有分區後,您可以在不影響當前分區的情況下對舊分區執行維護(刪除,複製等)。

+1

他擔心將表鎖定足夠長的時間來選擇,並且您建議添加分區方案?我敢肯定,這也會導致一些鎖定...... – JNK 2012-02-13 21:04:43

+0

@JNK是的,但這可能是未來計劃停機時間的一部分 – 2012-02-13 21:12:42

相關問題