删除大表中所有数据的最快方法

时间:2008-09-15 15:48:34

标签: sql-server tsql

我不得不从包含大约500万行的日志表中删除所有行。我最初的尝试是在查询分析器中发出以下命令:

从client_log中删除

花了很长时间。

15 个答案:

答案 0 :(得分:76)

查看速度更快的truncate table

答案 1 :(得分:33)

我在msdn transact-SQL引用中发现了 TRUNCATE TABLE 。对于所有感兴趣的人,请注意:

TRUNCATE TABLE在功能上与DELETE语句完全相同,没有WHERE子句:两者都删除表中的所有行。但TRUNCATE TABLE比DELETE更快,使用更少的系统和事务日志资源。

DELETE语句一次删除一行,并在事务日志中为每个已删除的行记录一个条目。 TRUNCATE TABLE通过释放用于存储表数据的数据页来删除数据,并且只有页面解除分配记录在事务日志中。

TRUNCATE TABLE从表中删除所有行,但表结构及其列,约束,索引等仍然存在。标识用于新行的计数器将重置为列的种子。如果要保留身份计数器,请改用DELETE。如果要删除表定义及其数据,请使用DROP TABLE语句。

您不能在FOREIGN KEY约束引用的表上使用TRUNCATE TABLE;相反,使用不带WHERE子句的DELETE语句。由于未记录TRUNCATE TABLE,因此无法激活触发器。

TRUNCATE TABLE不能用于参与索引视图的表。

答案 2 :(得分:15)

有一个共同的神话,TRUNCATE以某种方式跳过事务日志。

这是误解,在MSDN中明确提到。

这个神话在这里的几条评论中被引用。让我们一起消除它;)

答案 3 :(得分:6)

供参考TRUNCATE TABLE也适用于MySQL

答案 4 :(得分:3)

忘记截断并删除。维护你的表定义(如果你想重新创建它),只需使用drop table。

答案 5 :(得分:3)

我使用以下方法将表归零,并为表格的归档副本留下额外的好处。

CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;

答案 6 :(得分:1)

在SQL Server上,您可以使用Truncate Table命令,该命令比常规删除更快,并且使用的资源也更少。它还会将任何标识字段重置为种子值。

truncate的缺点是它不能用于外键引用的表,也不会触发任何触发器。如果出现任何问题,您也无法回滚数据。

答案 7 :(得分:1)

truncate table 独立于SQL平台。如果您怀疑可能更改了数据库提供程序,则可能需要谨慎使用它。

答案 8 :(得分:1)

请注意,如果您使用的话,TRUNCATE也会重置任何自动递增键。

如果您不希望丢失自动递增键,则可以通过删除多组来加速删除(例如,DELETE FROM表WHERE id> 1 AND id< 10000)。它会显着加快速度,并在某些情况下防止数据被锁定。

答案 9 :(得分:0)

是的,好吧,删除500万行可能需要很长时间。我能想到的唯一可能更快的方法是删除表,然后重新创建它。当然,只有在您想删除表格中的所有数据时,这才有效。

答案 10 :(得分:0)

截断表client_log

是你最好的选择,truncate会杀死表格和索引中的所有内容并重置你已经拥有的任何种子。

答案 11 :(得分:0)

“删除并重新创建表格”的建议可能不是一个好主意,因为这会占用您的外键。

您正在使用外键,对吧?

答案 12 :(得分:0)

我正在修改我先前的陈述:

  

你应该通过使用来理解   TRUNCATE数据将被清除但是   什么都不会记录到   交易日志。写入日志   这就是为什么DELETE将永远留在5   百万行。我经常使用TRUNCATE   在开发过程中,你应该是   担心在生产中使用它   数据库,因为你将无法做到   回滚您的更改。你应该   立即建立一个完整的数据库   执行TRUNCATE后备份   为恢复奠定新的基础。

上述声明旨在提示您确定您了解两者之间存在差异。不幸的是,由于我实际上没有在两者之间进行任何测试,因此编写得很糟糕且声明不受支持。它基于我从别人那里听到的陈述。

来自MSDN

  

DELETE语句删除第一行   一次并记录一个条目   每个已删除行的事务日志。   TRUNCATE TABLE删除数据   解除分配以前的数据页面   存储表的数据,只有   页面解除分配记录在   交易日志。

我只是想说两者之间存在根本区别,因为存在差异,会有应用程序中的一个或另一个可能不合适。

答案 13 :(得分:0)

如果由于外键和/或触发器而无法使用TRUNCATE TABLE,则可以考虑:

  • 删除所有索引;
  • 做通常的DELETE;
  • 重新创建所有索引。

这可能会加速DELETE。

答案 14 :(得分:-1)

DELETE * FROM table_name;

过早优化可能很危险。优化可能意味着做一些奇怪的事情,但如果它有效,你可能想要利用它。

SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;

速度我认为这取决于......

  • 底层数据库:Oracle,Microsoft,MySQL,PostgreSQL,其他,自定义......

  • 表格,内容和相关表格:

可能有删除规则。是否存在删除表中所有内容的现有过程?这可以针对特定的底层数据库引擎进行优化吗?我们关心破坏事物/相关数据多少钱?假设其他相关表不依赖于此表,执行DELETE可能是“最安全”的方式。是否存在与此表中的数据相关/依赖的其他表和查询?如果我们不关心这个表是什么,使用DROP可能是一个快速的方法,同样取决于底层数据库。

DROP TABLE table_name;

正在删除多少行?是否有其他快速收集的信息可以优化删除?例如,我们可以判断表是否已空?我们可以判断是否有数百,数千,数百万,数十亿行?