当'truncate table'需要0次时,为什么'从表中删除'需要很长时间?

时间:2008-12-24 18:48:03

标签: sql mysql performance truncate

(我在MySql中试过这个)

我相信它们在语义上是等价的。为什么不找出这个微不足道的案例并加快速度呢?

6 个答案:

答案 0 :(得分:30)

truncate table无法回滚,就像删除并重新创建表一样。

答案 1 :(得分:23)

...只是添加一些细节。

调用DELETE语句会告诉数据库引擎生成已删除的所有记录的事务日志。如果删除错误,您可以恢复记录。

调用TRUNCATE语句是一个“全有或全无”的毯子,它删除所有没有要从中恢复的事务日志的记录。它肯定更快,但只有当你确定不需要任何你要删除的记录时才应该这样做。

答案 2 :(得分:8)

从表中删除一次删除一行中的每一行,并将记录添加到事务日志中,以便可以回滚操作。删除所花费的时间也与表上的索引数成比例,并且是否存在任何外键约束(对于innodb)。

Truncate会有效地删除表并重新创建它,并且无法在事务中执行。因此,它需要更少的操作并快速执行。截断也不使用任何删除触发器。

可以在MySql文档中找到有关为什么在MySql中更快的详细信息: http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html

答案 3 :(得分:6)

你的问题是关于MySQL的,我对MySQL作为产品知之甚少,但我想我会在SQL Server中添加一个TRUNCATE语句可以回滚。亲自试试

create table test1 (col1 int)
go
insert test1 values(3)
begin tran
truncate table test1
select * from test1
rollback tran
select * from test1

在SQL Server中记录了TRUNCATE,它只是没有以记录DELETE的冗长方式登录。我相信它被称为最小化记录操作。实际上,数据页仍然包含数据,但它们的范围已被标记为删除。只要数据页仍然存在,您就可以回滚截断。希望这是有帮助的。如果有人在MySQL上尝试,我有兴趣知道结果。

答案 4 :(得分:1)

对于使用InnoDb作为存储引擎的MySql 5,TRUNCATE就像没有WHERE子句的DELETE一样:对于大型表,它需要很长时间,因为它逐个删除行。这在6.x版本中正在发生变化。

http://dev.mysql.com/doc/refman/5.1/en/truncate-table.html

用于5.1信息(与InnoDB一行一行)和

http://blogs.mysql.com/peterg/category/personal-opinion/

6.x

中的更改

编者注

这个答案是clearly contradicted by the MySQL documentation

“对于版本5.0.3之前的InnoDB表,InnoDB通过逐个删除行来处理TRUNCATE TABLE。从MySQL 5.0.3开始,只有在引用表的任何FOREIGN KEY约束时才使用逐行删除。如果没有FOREIGN KEY约束,InnoDB会通过删除原始表并创建一个具有相同定义的空表来执行快速截断,这比逐个删除行要快得多。“

答案 5 :(得分:0)

Truncate在表级别上,而Delete在行级别上。如果你想用其他语法将它翻译成sql,truncate将是:

DELETE * FROM table

因此一次删除所有行,而DELETE语句(在PHPMyAdmin中)如下:

DELETE * FROM table WHERE id = 1
DELETE * FROM table WHERE id = 2

直到桌子为空。每个查询都需要花费很多(毫秒)的时间,而这些查询的累计时间比截断的时间长。