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

Sql server 删除大型表中所有数据的最快方法,sql-server,tsql,Sql Server,Tsql,我必须从包含大约500万行的日志表中删除所有行。我最初尝试在查询分析器中发出以下命令: 从客户端日志中删除 这花了很长时间。请查看速度快得多的行。是的,删除500万行可能需要很长时间。我能想到的唯一可能更快的方法是删除表,然后重新创建它。当然,这只适用于要删除表中所有数据的情况。截断表客户机日志 CREATE TABLE `new_table` LIKE `table`; RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;

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

从客户端日志中删除


这花了很长时间。

请查看速度快得多的行。

是的,删除500万行可能需要很长时间。我能想到的唯一可能更快的方法是删除表,然后重新创建它。当然,这只适用于要删除表中所有数据的情况。

截断表客户机日志

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

truncate是您最好的选择,它会删除表中的所有内容,并索引和重置所有种子。

在SQL Server上,您可以使用
truncate table
命令,该命令比常规删除更快,而且使用的资源更少。它还会将所有标识字段重置回种子值


truncate的缺点是不能在外键引用的表上使用,也不会触发任何触发器。此外,如果出现任何错误,您将无法回滚数据。

我在msdn transact-SQL引用中发现了截断表。对于所有感兴趣的人,以下是备注:

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

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

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

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


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

作为参考也适用于MySQL

TRUNCATE TABLE
与SQL平台无关。如果您怀疑您可能会更改数据库提供程序,那么您可能会对使用数据库提供程序持谨慎态度。

关于“删除并重新创建表”的建议可能不是一个好建议,因为这会弄乱外键


您使用的是外键,对吗?

请注意,如果您使用的是自动递增键,TRUNCATE也会重置这些键


如果不希望丢失自动递增键,可以通过集中删除来加快删除速度(例如,从id>1和id<10000的表中删除)。它将大大加快速度,在某些情况下还可以防止数据被锁定。

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

你应该通过使用 截断数据将被清除,但 不会将任何内容记录到日志中 事务日志。写入日志 这就是为什么删除将永远持续5天 百万行。我经常使用TRUNCATE 在开发过程中,但您应该 对在生产中使用它持谨慎态度 数据库,因为您将无法 回滚您的更改。你应该 立即建立完整的数据库 执行截断后备份到 建立新的恢复基础

上述声明旨在提醒您确保您了解两者之间的差异。不幸的是,它写得很糟糕,并且做出了不受支持的声明,因为我实际上没有在两者之间进行任何测试。这是基于我从其他人那里听到的陈述

发件人:

DELETE语句将删除一行 并在 每个已删除行的事务日志。 TRUNCATE TABLE通过以下方式删除数据: 取消分配用于 存储表的数据,并且仅存储 页面解除分配记录在 事务日志


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

有一个常见的误解,即截断会以某种方式跳过事务日志

这是一种误解,MSDN中明确提到了这一点


这里有几条评论引用了这个神话。让我们一起根除它;)

> P>如果由于外键和/或触发器不能使用截断表,则可以考虑:

  • 删除所有索引
  • 执行通常的删除操作
  • 重新创建所有索引

这可能会加快删除速度。

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

我使用以下方法将表归零,还有一个额外的好处,那就是它给我留下了一个表的存档副本

CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;
过早优化可能是危险的。优化可能意味着做一些奇怪的事情,但如果它起作用,你可能想利用它

SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;
至于速度,我认为这取决于

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

  • 表格、其内容和相关表格:

可能存在删除规则。是否存在删除表中所有内容的现有程序?是否可以针对特定的底层数据库引擎对此进行优化?我们对破坏事物/相关数据有多在意?假设其他相关表不依赖于此表,则执行删除可能是“最安全”的方式。是否有其他与/dep相关的表和查询
DROP TABLE table_name;