16

(我已经在 MySql 中尝试过)

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

4

6 回答 6

30

truncate table 不能回滚,就像删除和重新创建表一样。

于 2008-12-24T18:50:08.913 回答
23

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

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

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

于 2008-12-24T18:52:29.690 回答
9

Delete from table 一次删除一行中的每一行,并在事务日志中添加一条记录,以便可以回滚操作。删除所花费的时间也与表上的索引数量成正比,以及是否有任何外键约束(对于 innodb)。

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

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

于 2008-12-24T18:53:50.747 回答
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 上尝试它,我很想知道结果。

于 2008-12-25T16:16:43.467 回答
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 中的更改


编者注

这个答案显然与 MySQL 文档相矛盾

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

于 2009-09-25T11:05:27.277 回答
-1

截断是在表级别,而删除是在行级别。如果您将其转换为其他语法的 sql,则 truncate 将是:

DELETE * FROM table

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

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

直到桌子空了。每个查询花费数(毫秒)秒,加起来比截断花费的时间更长。

于 2013-08-14T09:50:10.830 回答