我在响应写了一个回答这个问题的错误到一个问题有关的区别TRUNCATE
和DELETE
,但我认为这是一个耻辱不共享,所以我会后我自己的答案,以我自己的问题...的是,即使道德?:)
编辑:如果您的答案是平台特定的,请指出.
这是一个差异列表.我已经强调了Oracle特有的功能,希望社区也可以添加其他供应商的特定差异.大多数供应商常见的差异可以直接在标题下方,下面突出显示差异.
如果你想快速删除表中的所有行,并且你确实想要这样做,并且你没有对表的外键,那么TRUNCATE可能会比DELETE更快.
必须考虑各种系统特定问题,详情如下.
删除是DML,Truncate是DDL
供应商可变
SQL*服务器
截断可以回滚.
PostgreSQL的
截断可以回滚.
神谕
因为TRUNCATE是DDL,所以它涉及两个提交,一个在语句执行之前,一个在语句执行之后.因此,Truncate不能回滚,并且truncate进程中的失败无论如何都会发出提交.
但是,请参阅下面的Flashback.
删除不会恢复空间,Truncate会恢复空间
神谕
如果使用REUSE STORAGE子句,则不会取消分配数据段,如果要重新装入数据表,则可以稍微提高效率.高水位标记被重置.
删除可用于删除所有行或仅删除行的子集.截断删除所有行.
神谕
对表进行分区时,可以单独截断各个分区,从而可以部分删除所有表的数据.
删除可以应用于群集内的表和表.截断仅适用于表或整个群集.(可能是Oracle特定的)
神谕
删除不会影响数据对象ID,但truncate会分配一个新的数据对象id,除非从创建以来从未对表进行过插入即使回滚的单个插入也会导致在截断时分配新的数据对象id .
闪回可以跨删除工作,但截断可以防止闪回到操作之前的状态.
但是,从11gR2开始,FLASHBACK ARCHIVE功能允许这样,除了Express Edition
在Oracle中使用FLASHBACK http://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_flashback.htm#ADFNS638
变量
神谕
删除可以在表上授予另一个用户或角色,但截断不能不使用DROP ANY TABLE授权.
删除会生成少量重做和大量撤消.截断每个产生的数量可以忽略不计.
神谕
截断操作会再次使用不可用的索引.删除没有.
当启用的外键引用表时,无法应用截断.删除处理取决于外键的配置.
神谕
Truncate需要一个独占表锁,delete需要一个共享表锁.因此,禁用表锁是一种阻止对表进行截断操作的方法.
DML触发器不会触发截断.
神谕
DDL触发器可用.
神谕
无法通过数据库链接发出截断.
SQL*服务器
截断重置IDENTITY列类型的序列,删除不重复.
在大多数实现中,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从表中删除所有行.无法回滚操作,也不会触发任何触发器.因此,TRUCATE更快,并且不使用与DELETE一样多的撤消空间.
删除
DELETE命令用于从表中删除行.WHERE子句可用于仅删除某些行.如果未指定WHERE条件,则将删除所有行.执行DELETE操作后,您需要COMMIT或ROLLBACK事务以使更改成为永久更改或撤消它.请注意,此操作将导致触发表上的所有DELETE触发器.
来自:http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands
所有好的答案,我必须补充:
既然TRUNCATE TABLE
是DDL(数据定义语言),而不是DML(Data Manipulation Langauge)命令,Delete Triggers
则不运行.
删除Vs摘要在SQL服务器中截断
完整文章请点击此链接:http://codaffection.com/sql-server-article/delete-vs-truncate-in-sql-server/
取自dotnet mob文章:在SQL Server中删除Vs截断
对于SQL Server或MySQL,如果存在具有自动增量的PK,则truncate将重置计数器.
"截断不记录任何东西"是正确的.我走得更远:
截断不在事务的上下文中执行.
truncate over delete的速度优势应该是显而易见的.根据您的具体情况,这种优势从琐碎到巨大.
但是,我看到truncate无意中破坏了引用完整性,并违反了其他约束.通过修改事务外部数据而获得的权力必须与您在没有网络的情况下走钢丝时所承担的责任相平衡.
TRUNCATE
是DDL语句,DELETE
而是DML语句.以下是两者之间的差异:
与TRUNCATE
DDL(数据定义语言)语句一样,它不需要提交来使更改成为永久更改.这就是为什么truncate删除的行无法回滚的原因.另一方面DELETE
,DML(数据操作语言)语句因此需要显式提交以使其效果永久化.
TRUNCATE
始终从表中删除所有行,使表保持空,表结构保持不变,DELETE
但如果使用where子句,则可以有条件地删除.
TRUNCATE TABLE
无法恢复由语句删除的行,也无法在语句中指定where子句TRUNCATE
.
TRUNCATE
语句不会触发触发器,而不是触发DELETE
语句上的delete触发器
这是与该主题相关的非常好的链接.
是的,DELETE较慢,TRUNCATE更快.为什么?
DELETE必须读取记录,检查约束,更新块,更新索引以及生成重做/撤消.所有这些都需要时间.
TRUNCATE只是调整数据库中的表格(高水位线)和噗!数据消失了.
这是Oracle特定的,AFAIK.
如果意外地使用Delete/Truncate从表中删除了所有数据.您可以回滚已提交的事务.恢复上次备份并运行事务日志,直到删除/截断即将发生.
以下相关信息来自博客文章:
在处理数据库时,我们使用Delete和Truncate而不知道它们之间的差异.在本文中,我们将讨论Sql中Delete和Truncate之间的区别.
删除:
删除是DML命令.
使用行锁执行Delete语句,表中的每一行都被锁定以进行删除.
我们可以在where子句中指定过滤器.
如果条件存在,它将删除指定的数据.
将活动删除为触发器,因为操作是单独记录的.
比Truncate慢,因为它保留了日志
截短
Truncate是一个DDL命令.
截断表总是锁定表和页,但不是每行.因为它删除了所有数据.
不能使用Where条件.
它删除所有数据.
截断表无法激活触发器,因为该操作不会记录单个行删除.
性能更快,因为它不保留任何日志.
注意:与Transaction一起使用时,可以回滚Delete和Truncate.如果Transaction已完成,则表示我们无法回滚Truncate命令,但我们仍然可以从Log文件回滚Delete命令,因为删除写入将它们记录在Log文件中,以防将来需要从日志文件回滚.
如果您有一个外键约束引用您尝试截断的表,即使引用表中没有数据,这也不起作用.这是因为外键检查是使用DDL而不是DML完成的.这可以通过暂时禁用表的外键约束来解决.
删除表是记录的操作.因此,每行的删除都会记录在事务日志中,这会使其变慢.截断表还删除表中的所有行,但它不会记录每行的删除,而是记录表的数据页的重新分配,这使得它更快.
〜如果意外地使用Delete/Truncate从表中删除了所有数据.您可以回滚已提交的事务.恢复上次备份并运行事务日志,直到删除/截断即将发生.