如何在不使日志文件失控的情况下从大表中删除过期数据?

pol*_*nts 7 sql sql-server-2005 transaction-log bulk sql-delete

我有一个巨大的表(30亿行),不幸的是,它包含大部分过期的数据.我想简单地删除所有这些过期的行,并保留其余的行.

我可以执行这样的语句:

delete from giganticTable where exp_date < getDate()
Run Code Online (Sandbox Code Playgroud)

执行计划以某种方式估计将删除大约4亿行.

执行时,不仅在一小时后没有完成,而且数据库事务日志文件也从6 GB增长到90 GB.请注意,在发生这种情况时,数据库处于批量记录恢复模型中.我最终取消了这个查询,因为我确信必须有更好的方法来做到这一点.

我有几个表需要执行类似的操作.如果我绝对不想恢复它们,那么删除这些行的最快和最节省空间的方法是什么?

请注意,我正在使用Microsoft SQL Server 2005.

rsb*_*rro 9

我发现从具有大量行的表中删除以删除批量为5000左右的行时,我发现它很有用(我通常会测试哪个值工作最快,有时候是5000行,有时是10000行等) .这允许每个删除操作快速完成,而不是等待很长时间一个语句来淘汰4亿条记录.

在SQL Server 2005中,这样的东西应该工作(当然,请先测试):

WHILE EXISTS ( SELECT * FROM giganticTable WHERE exp_date < getDate())
BEGIN
  DELETE TOP(5000) FROM giganticTable WHERE exp_date < getDate()
END
Run Code Online (Sandbox Code Playgroud)

我会看到批量删除对日志文件大小的影响.如果它仍在炸毁日志,那么您可以尝试将恢复模型更改为简单,删除记录,然后切换回批量记录,但前提是系统可以容忍丢失一些最近的数据.在尝试该程序之前,我肯定会进行完全备份.此线程还建议您可以设置作业来备份仅指定了truncate的日志,这可能是另一种选择.希望您有一个可以测试的实例,但我会从批量删除开始,看看它如何影响性能和日志文件大小.


IAm*_*rey 3

当您想在表上做大量工作时,您真的不想尝试任何愚蠢的事情,例如关闭日志记录,因为长时间任务期间的任何问题都可能很容易导致数据库损坏和其他问题。但是,有一种方法可以解决您的问题。

创建一个与实际表的架构匹配的临时表。用您想要保留的数据填充它。然后,截断原始表(在日志文件上非常快速且简单)。最后,将数据从临时表中移出并移入原始(现在为空)表中。

如果您使用自动递增主键,则需要强制字段采用原始键(这样以后就不会出现问题)。