SQL中TRUNCATE和DELETE的区别是什么?

如果你的答案是针对特定平台的,请注明。


当前回答

简而言之,truncate不会记录任何内容(因此更快,但不能撤消),而delete会记录日志(并且可以是更大事务的一部分,将回滚等)。如果您在开发中有不想在表中使用的数据,通常最好截断,因为您不会冒填满事务日志的风险

其他回答

并不是说截断不记录SQL Server中的任何内容。truncate不记录任何信息,但它记录您触发truncate的表的数据页的释放。

如果在开始时定义事务,则可以回滚被截断的记录,回滚后可以恢复被截断的记录。但不能在提交截断事务后从事务日志备份中恢复截断记录。

TRUNCATE是快的,DELETE是慢的。

尽管TRUNCATE没有问责制。

下面是一些不同之处。我强调了特定于oracle的特性,希望社区也能添加其他供应商的特定差异。对于大多数供应商来说常见的差异可以直接放在标题下面,并在下面突出显示差异。

总体概述

如果您想要快速删除表中的所有行,并且您确实确定要这样做,并且表上没有外键,那么TRUNCATE可能会比delete更快。

必须考虑各种特定于系统的问题,详情如下。

语句类型

删除是DML,截断是DDL(什么是DDL和DML?)

提交和回滚

供应商变量

SQL *服务器

Truncate可以回滚。

PostgreSQL

Truncate可以回滚。

甲骨文

因为TRUNCATE是DDL,它涉及两次提交,一次在语句执行之前,一次在语句执行之后。因此,Truncate不能回滚,截断过程中的失败无论如何都会发出提交。

然而,请看下面的闪回。

空间回收

Delete不能恢复空间,Truncate只能恢复空间

甲骨文

如果使用了REUSE STORAGE子句,那么数据段就不会被重新分配,如果要用数据重新加载表,这样做的效率会稍微高一些。重置高水位标志。

行范围

Delete可用于删除所有行或仅删除行的子集。Truncate删除所有行。

甲骨文

在对表进行分区时,可以隔离地截断各个分区,从而可以部分删除表的所有数据。

对象类型

Delete可以应用于集群内的表和表。Truncate仅适用于表或整个集群。(可能是Oracle特有的)

数据对象标识

甲骨文

Delete不会影响数据对象id,但truncate会分配一个新的数据对象id,除非自该表创建以来从未对该表进行过插入操作。即使是一个回滚的插入操作也会导致在截断时分配一个新的数据对象id。

闪回(Oracle)

闪回可以跨删除操作,但截断操作可以防止闪回操作之前的状态。

然而,从11gR2 FLASHBACK ARCHIVE功能允许这一点,除了在快速版

在Oracle中使用FLASHBACK http://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_flashback.htm#ADFNS638

特权

变量

甲骨文

可以将一个表上的Delete授权给另一个用户或角色,但是截断不能不使用DROP ANY table授权。

Redo /。

删除会产生少量的重做和大量的撤销。Truncate生成的两者数量都可以忽略不计。

索引

甲骨文

截断操作使不可用的索引重新可用。删除则不然。

外键

当启用的外键引用表时,不能应用截断。使用delete的处理取决于外键的配置。

表锁

甲骨文

Truncate需要一个排他表锁,delete需要一个共享表锁。因此,禁用表锁是防止对表进行截断操作的一种方法。

触发器

DML触发器不会在截断时触发。

甲骨文

DDL触发器是可用的。

远程执行

甲骨文

不能在数据库链接上发出Truncate命令。

标识列

SQL *服务器

Truncate重置IDENTITY列类型的序列,delete则不会。

结果集

在大多数实现中,DELETE语句可以向客户端返回已删除的行。

例如,在Oracle PL/SQL子程序中,你可以:

DELETE FROM employees_temp
WHERE       employee_id = 299 
RETURNING   first_name,
            last_name
INTO        emp_first_name,
            emp_last_name;

通过发出TRUNCATE TABLE语句,您将指示SQL Server删除表中的每条记录,而不进行任何日志记录或事务处理。

SQL server中删除与截断的总结 完整文章请点击这个链接:http://codaffection.com/sql-server-article/delete-vs-truncate-in-sql-server/

摘自dotnet mob文章:删除Vs截断SQL Server