2012-02-13 49 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

相关问题