TRUNCATE
和 DELETE
在 SQL 中有什么区别?
如果你的回答与平台相关,请注明。
TRUNCATE
和 DELETE
在 SQL 中有什么区别?
如果你的回答与平台相关,请注明。
以下是一些不同之处。我突出了 Oracle 特定的功能,希望社区可以添加其他供应商的特定差异。对于大多数供应商通用的差异,可以直接放在标题下面,差异则在下面突出。
如果您想快速删除表中的所有行,并且确实确定想要这样做,并且没有针对该表的外键,则 TRUNCATE 可能比 DELETE 更快。
必须考虑各种系统特定问题,如下所述。
Delete 是 DML,Truncate 是 DDL(什么是 DDL 和 DML?)
根据供应商而变化
SQL*Server
Truncate 可以回滚。
PostgreSQL
Truncate 可以回滚。
Oracle
由于 TRUNCATE 是 DDL,它涉及两个提交,一个在语句执行之前,一个在之后。因此,TRUNCATE 无法回滚,并且在 TRUNCATE 过程中失败将已经发出提交。
但是,请参见下面的 Flashback。
Delete 不会恢复空间,Truncate 会恢复空间。
Oracle
如果使用 REUSE STORAGE 子句,则数据段不会被取消分配,如果要重新加载数据,则可能稍微更高效。高水位线被重置。
Delete 可用于删除所有行或仅子集行。Truncate 删除所有行。
Oracle
当表被分区时,各个分区可以被独立地截断,因此可以部分删除整个表的数据。
可以将删除应用于表和集群内的表。截断仅适用于表或整个集群。(可能是Oracle特有的)
Oracle
Delete不会影响数据对象ID,但截断会分配一个新的数据对象ID,除非自创建表以来从未对表进行过插入操作。即使单个回滚的插入也会导致在截断时分配新的数据对象ID。
闪回适用于删除操作,但截断会阻止返回到操作之前的状态。
但是,从11gR2开始,FLASHBACK ARCHIVE功能允许执行此操作,除了Express Edition。
在Oracle中使用FLASHBACK http://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_flashback.htm#ADFNS638
可变量
Oracle
可以将删除授权给另一个用户或角色,但是截断不能,除非使用DROP ANY TABLE授予。
Delete生成少量重做和大量撤销。截断生成微不足道的每个数量。
Oracle
截断操作使不可用的索引再次可用。删除不行。
如果启用了外键引用该表,则无法使用截取(truncate)操作,需要根据外键的配置来决定是否使用删除(delete)操作。
Oracle
截取(Truncate)操作需要独占表锁,删除(delete)操作需要共享表锁。因此,禁用表锁是防止对表进行截取操作的一种方法。
截取(truncate)操作不会触发DML触发器。
Oracle
DDL触发器可用。
Oracle
无法通过数据库链接进行截取(truncate)操作。
SQL*Server
截取(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 | 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) |
+----------------------------------------+----------------------------------------------+
DROP命令从数据库中删除一个表。所有该表的行、索引和权限也将被删除。不会触发任何DML触发器。此操作无法回滚。
TRUNCATE从表中删除所有行。此操作无法回滚,也不会触发任何触发器。因此,TRUNCATE速度更快,使用的撤消空间也比DELETE少。在截断时,将添加表级锁。
DELETE命令用于从表中删除行。可以使用WHERE子句仅删除某些行。如果未指定WHERE条件,则将删除所有行。执行DELETE操作后,需要提交或回滚事务以使更改永久生效或撤消更改。请注意,此操作将导致表上的所有DELETE触发器触发。在删除时,将添加行级锁。
来自:http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands
SQL Server中删除(Delete)和截断(Truncate)的概述
完整文章请访问:http://codaffection.com/sql-server-article/delete-vs-truncate-in-sql-server/
摘自dotnet mob文章:SQL Server中的Delete与Truncate
使用SQL Server或MySQL,如果有一个带自增的主键(PK),那么截断(truncate)操作将会重置该计数器。
DBCC CHECKIDENT (table_name,RESEED,1)
。 - JohnB"Truncate不会记录任何信息"是正确的。我会进一步说明:
在事务上下文中不会执行truncate。
相对于delete,truncate的速度优势应该是显而易见的。根据您的情况,这种优势从微不足道到巨大不等。
然而,我曾经看到过truncate无意中破坏了引用完整性并违反了其他约束条件。在没有事务支持的情况下修改数据所获得的权力必须与在没有保障的情况下行走钢丝时承担的责任相平衡。
TRUNCATE
是DDL语句,而DELETE
是DML语句。以下是两者之间的区别:
TRUNCATE
是DDL(数据定义语言)语句,因此不需要提交以使更改永久生效。这就是为什么通过truncate删除的行无法回滚的原因。另一方面,DELETE
是DML(数据操作语言)语句,因此需要显式提交以使其效果永久。
TRUNCATE
总是从表中删除所有行,使表为空,表结构保持不变,而DELETE
可以根据使用where子句来有条件地删除。
通过TRUNCATE TABLE
语句删除的行不能恢复,并且在TRUNCATE
语句中不能指定where子句。
TRUNCATE
语句不会触发触发器,而DELETE
语句上的on delete触发器则相反。
这里是与该主题相关的非常好的链接。
是的,DELETE比TRUNCATE慢。为什么呢?
DELETE必须读取记录、检查约束条件、更新块、更新索引并生成重做/撤销信息,所有这些都需要时间。
TRUNCATE只需调整表在数据库中的指针(高水位线),数据就会消失。
据我所知,这只适用于Oracle。