批量删除(截断与删除)
Posted
技术标签:
【中文标题】批量删除(截断与删除)【英文标题】:Bulk delete (truncate vs delete) 【发布时间】:2010-12-18 21:10:26 【问题描述】:我们有一个包含 150+ 百万条记录的表。我们需要清除/删除所有行。由于写入 t-logs,删除操作将永远持续下去,我们无法更改整个数据库的恢复模式。我们已经测试了 truncate table 选项。
我们意识到 truncate 会从表中取消分配页面,如果我没记错的话,可以使它们可用于重用,但不会自动缩小数据库。因此,如果我们想减小 DB 大小,我们确实需要在截断表后运行 shrink db 命令。
这是正常程序吗?有什么需要我们注意或注意的,或者有更好的选择吗?
【问题讨论】:
【参考方案1】:truncate
是您正在寻找的。如果您之后需要缩小数据库,请运行收缩。
这个MSDN refernce(如果你说的是 T-SQL)比较了删除行和截断的幕后情况。
【讨论】:
正如其他 cmets 所指出的,无论您选择哪种方法,您都必须处理外键约束(如果有)。我的偏好是禁用约束,truncate
表,重新启用约束,然后 dbcc shirinkfile
(给自己一些时间)。【参考方案2】:
“删除所有行”... DROP TABLE(并重新创建具有相同架构/索引的空表)不是更可取吗? (我个人喜欢“新的开始” ;-))
这个说的TRUNCATE TABLE也很好,是的,如果你想恢复空间,后面可能需要DBCC SHRINKFILE。
【讨论】:
【参考方案3】:根据整个数据库的大小,收缩可能需要一段时间;我发现如果将其缩小为更小的块,它会运行得更快,而不是试图一次将其全部恢复。
【讨论】:
【参考方案4】:使用截断表(以及删除表)要记住的一点是,如果您曾经有外键引用该表,这将不起作用。
【讨论】:
在 SQL Server 上,如果存在外键约束,则无法使用drop table
。 msdn.microsoft.com/en-us/library/ms173790.aspx
@prokiner 无论如何,您都必须处理外键引用,即无论行是否被删除、缩小或删除,引用该行的其他表中的任何记录都必须是首先删除或删除约束。在某些情况下,这可能是使用 ON DELETE 触发器“自动”完成的,但这几乎不适用于 150+ 百万类型的数据库。
@prokiner,我应该更清楚。这些本来是两个独立的想法,我只是指出问题是 OP 表示他们已经测试了截断方法。我已经清理了我的答案。
@Irwin - 抱歉我也不太清楚。你是对的,这两种方法都需要处理外键约束。我的评论只是处理drop
选项。无论哪种情况,OPer 的工作量都比简单的truncate table; dbcc shrinkfile
多。
@mjv - 你是对的。还有一件事要记住,truncate table
不会激活触发器,但 delete
会。【参考方案5】:
正如所指出的,如果你不能使用 truncate 或 drop
SELECT 1
WHILE @@ROWCOUNT <> 0
DELETE TOP (100000) MyTable
【讨论】:
他可以同时使用 truncate 或 drop,但是对于必须处理的任何操作(delete、drop、truncate)来说,它们都是可能的考虑因素。【参考方案6】:您有一个正常的解决方案(截断 + 收缩 db)来删除表中的所有记录。
正如欧文指出的那样。 TRUNCATE 命令在被外键约束引用时不起作用。所以首先删除约束,截断表并重新创建约束。
如果您担心性能 和,这是您系统的常规例程。您可能想考虑将此表移动到它自己的数据文件中,然后运行只针对目标数据文件收缩!
【讨论】:
以上是关于批量删除(截断与删除)的主要内容,如果未能解决你的问题,请参考以下文章