我不得不从包含大约500万行的日志表中删除所有行。我最初的尝试是在查询分析器中发出以下命令:
从client_log中删除
花了很长时间。
答案 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。
答案 14 :(得分:-1)
DELETE * FROM table_name;
过早优化可能很危险。优化可能意味着做一些奇怪的事情,但如果它有效,你可能想要利用它。
SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;
速度我认为这取决于......
底层数据库:Oracle,Microsoft,MySQL,PostgreSQL,其他,自定义......
表格,内容和相关表格:
可能有删除规则。是否存在删除表中所有内容的现有过程?这可以针对特定的底层数据库引擎进行优化吗?我们关心破坏事物/相关数据多少钱?假设其他相关表不依赖于此表,执行DELETE可能是“最安全”的方式。是否存在与此表中的数据相关/依赖的其他表和查询?如果我们不关心这个表是什么,使用DROP可能是一个快速的方法,同样取决于底层数据库。
DROP TABLE table_name;
正在删除多少行?是否有其他快速收集的信息可以优化删除?例如,我们可以判断表是否已空?我们可以判断是否有数百,数千,数百万,数十亿行?