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

时间:2020-03-05 18:53:47  来源:igfitidea点击:

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

从client_log删除

这花了很长时间。

解决方案

回答

检出截断表,该表要快得多。

回答

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

回答

<I>截断表client_log

是最好的选择,截断会杀死表中的所有内容并建立索引,并重置我们拥有的所有种子。

回答

在SQL Server上,可以使用" Truncate Table"命令,该命令比常规删除要快,并且使用的资源也较少。它将所有身份字段也重置回种子值。

截断的缺点是它不能在外键引用的表上使用,并且不会触发任何触发器。此外,如果出现任何问题,我们将无法回滚数据。

回答

我在msdn transact-SQL参考中发现了TRUNCATE TABLE。对于所有感兴趣的人,请注意以下几点:

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

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

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

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

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

回答

供参考TRUNCATE TABLE也可以在MySQL上使用

回答

truncate table不独立于SQL平台。如果我们怀疑自己曾经更改过数据库提供程序,则可能会警惕使用它。

回答

"删除并重新创建表"的建议可能不是一个好主意,因为这会破坏外键。

我们正在使用外键,对吗?

回答

请注意,如果正在使用TRUNCATE,它们还将重置所有自动递增键。

如果我们不想丢失自动递增键,则可以通过删除集合(例如,从ID为1且ID为<10000的表中的DELETE FROM table)来加快删除速度。它可以显着加快速度,在某些情况下还可以防止数据被锁定。

回答

我正在修改我先前的声明:

You should understand that by using
  TRUNCATE the data will be cleared but
  nothing will be logged to the
  transaction log.  Writing to the log
  is why DELETE will take forever on 5
  million rows.  I use TRUNCATE often
  during development, but you should be
  wary about using it on a production
  database because you will not be able
  to roll back your changes.  You should
  immediately make a full database
  backup after doing a TRUNCATE to
  establish a new basis for restoration.

以上声明旨在提示我们确保我们了解两者之间的区别。不幸的是,由于我实际上并未在两者之间进行任何测试,因此它编写得很差并且发表了不受支持的声明。它基于我从其他人那里听到的陈述。

从MSDN:

The DELETE statement removes rows one
  at a time and records an entry in the
  transaction log for each deleted row.
  TRUNCATE TABLE removes the data by
  deallocating the data pages used to
  store the table's data, and only the
  page deallocations are recorded in the
  transaction log.

我只是想说这两者之间存在根本差异,并且由于存在差异,因此在某些应用程序中,其中一种可能不合适。

回答

有一个普遍的神话,即TRUNCATE会以某种方式跳过事务日志。

这是一种误解,在MSDN中已明确提及。

在这里的一些评论中引用了这个神话。让我们一起消灭它吧;)

回答

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

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

这可能会加快DELETE的速度。

回答

忘记截断并删除。维护表定义(以防我们要重新创建表),只需使用drop table。

回答

我使用以下方法将表归零,这带来了额外的好处,那就是我留下了表的存档副本。

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

回答

DELETE * FROM table_name;

过早的优化可能很危险。优化可能意味着做一些奇怪的事情,但是如果可行,我们可能想利用它。

SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;

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

  • 基础数据库:Oracle,Microsoft,MySQL,PostgreSQL,其他,自定义...
  • 该表及其内容和相关表:

可能有删除规则。是否存在删除表中所有内容的现有过程?可以针对特定的基础数据库引擎对此进行优化吗?我们在乎破坏事物/相关数据有多少?假定其他相关表不依赖此表,则执行DELETE可能是"最安全"的方法。还有其他与该表中的数据相关/相关的表和查询吗?如果我们不太关心这个表的周围,那么使用DROP可能是一种快速的方法,再次取决于基础数据库。

DROP TABLE table_name;

删除了几行?是否有其他可以快速收集以优化删除的信息?例如,我们可以判断表是否已经为空?我们能否确定是否有成百上千的行?