SQL中TRUNCATE和DELETE的区别是什么?
如果你的答案是针对特定平台的,请注明。
SQL中TRUNCATE和DELETE的区别是什么?
如果你的答案是针对特定平台的,请注明。
当前回答
下面是一些不同之处。我强调了特定于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;
其他回答
下面是一些不同之处。我强调了特定于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;
它方便的一个重要原因是,当您需要刷新数百万行表中的数据,但又不想重新构建它时。“Delete *”会花费很长时间,而Truncate对性能的影响可以忽略不计。
一眨眼的功夫就不能做DDL。
truncate和delete的区别如下:
+----------------------------------------+----------------------------------------------+
| Truncate | Delete |
+----------------------------------------+----------------------------------------------+
| We can't Rollback after performing | We can Rollback after delete. |
| Truncate. | |
| | |
| Example: | Example: |
| BEGIN TRAN | BEGIN TRAN |
| TRUNCATE TABLE tranTest | DELETE FROM tranTest |
| SELECT * FROM tranTest | SELECT * FROM tranTest |
| ROLLBACK | ROLLBACK |
| SELECT * FROM tranTest | SELECT * FROM tranTest |
+----------------------------------------+----------------------------------------------+
| Truncate reset identity of table. | Delete does not reset identity of table. |
+----------------------------------------+----------------------------------------------+
| It locks the entire table. | It locks the table row. |
+----------------------------------------+----------------------------------------------+
| Its DDL(Data Definition Language) | Its DML(Data Manipulation Language) |
| command. | command. |
+----------------------------------------+----------------------------------------------+
| We can't use WHERE clause with it. | We can use WHERE to filter data to delete. |
+----------------------------------------+----------------------------------------------+
| Trigger is not fired while truncate. | Trigger is fired. |
+----------------------------------------+----------------------------------------------+
| Syntax : | Syntax : |
| 1) TRUNCATE TABLE table_name | 1) DELETE FROM table_name |
| | 2) DELETE FROM table_name WHERE |
| | example_column_id IN (1,2,3) |
+----------------------------------------+----------------------------------------------+
对于SQL Server或MySQL,如果有一个带有自动递增的PK, truncate将重置计数器。