批量删除(截断与删除)

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 命令在被外键约束引用时不起作用。所以首先删除约束,截断表并重新创建约束。

如果您担心性能 ,这是您系统的常规例程。您可能想考虑将此表移动到它自己的数据文件中,然后运行只针对目标数据文件收缩!

【讨论】:

以上是关于批量删除(截断与删除)的主要内容,如果未能解决你的问题,请参考以下文章

yii2 怎么批量删除

删除功能的实现(单个删除与批量删除)

React开发(171):处理删除与批量删除操作

React开发(171):处理删除与批量删除操作

批量删除与查询

vim的批量注释与删除注释