SQL中的TRUNCATE和DELETE有什么区别

Dav*_*dge 263 sql database truncate

我在响应写了一个回答这个问题的错误到一个问题有关的区别TRUNCATEDELETE,但我认为这是一个耻辱不共享,所以我会后我自己的答案,以我自己的问题...的是,即使道德?:)

编辑:如果您的答案是平台特定的,请指出.

Dav*_*dge 241

这是一个差异列表.我已经强调了Oracle特有的功能,希望社区也可以添加其他供应商的特定差异.大多数供应商常见的差异可以直接在标题下方,下面突出显示差异.


总体概述

如果你想快速删除表中的所有行,并且你确实想要这样做,并且你没有对表的外键,那么TRUNCATE可能会比DELETE更快.

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


声明类型

删除是DML,Truncate是DDL


提交和回滚

供应商可变

SQL*服务器

截断可以回滚.

PostgreSQL的

截断可以回滚.

神谕

因为TRUNCATE是DDL,所以它涉及两个提交,一个在语句执行之前,一个在语句执行之后.因此,Truncate不能回滚,并且truncate进程中的失败无论如何都会发出提交.

但是,请参阅下面的Flashback.


空间回收

删除不会恢复空间,Truncate会恢复空间

神谕

如果使用REUSE STORAGE子句,则不会取消分配数据段,如果要重新装入数据表,则可以稍微提高效率.高水位标记被重置.


行范围

删除可用于删除所有行或仅删除行的子集.截断删除所有行.

神谕

对表进行分区时,可以单独截断各个分区,从而可以部分删除所有表的数据.


对象类型

删除可以应用于群集内的表和表.截断仅适用于表或整个群集.(可能是Oracle特定的)


数据对象标识

神谕

删除不会影响数据对象ID,但truncate会分配一个新的数据对象id,除非从创建以来从未对表进行过插入即使回滚的单个插入也会导致在截断时分配新的数据对象id .


闪回(Oracle)

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

但是,从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;
Run Code Online (Sandbox Code Playgroud)

  • DELETE返回已删除的行数,但TRUNCATE不返回.这是非常愚蠢的点,但值得一提:) (4认同)

Bha*_*tel 179

截断和删除之间的区别如下:

+----------------------------------------+----------------------------------------------+
|                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)              |
+----------------------------------------+----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

  • @jWeaver:这意味着当您将主键字段的 Identity Specification 属性设置为 True 时,因此当您将数据插入该表时,主键列保存的值为 1,2,3,4,5....(如果 Identity 开始从 1 开始,种子为 1),当您截断表时,它将丢失所有标识值,因此当您再次开始向该表中插入数据时,它将从 1 开始,而不是从最后剩下的位置开始。在 DELETE 中,它是相反的,即使在您执行 DELETE 语句后,它也会保留标识值。很抱歉上图中 DELETE 列中的第二个比较点错误。 (2认同)
  • TRUNCATE和DELETE都可以在* SQL SERVER *中回滚。并且在第二行中DELETE不会重置身份。现在如何编辑这篇文章?那是在StackOverflow中使用图片的坏事。 (2认同)
  • 正在回滚截断!(SQL 服务器) (2认同)

Moh*_*ngh 44

下降

DROP命令从数据库中删除表.所有表的行,索引和权限也将被删除.不会触发任何DML触发器.该操作无法回滚.

截短

TRUNCATE从表中删除所有行.无法回滚操作,也不会触发任何触发器.因此,TRUCATE更快,并且不使用与DELETE一样多的撤消空间.

删除

DELETE命令用于从表中删除行.WHERE子句可用于仅删除某些行.如果未指定WHERE条件,则将删除所有行.执行DELETE操作后,您需要COMMIT或ROLLBACK事务以使更改成为永久更改或撤消它.请注意,此操作将导致触发表上的所有DELETE触发器.

来自:http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands

  • 像我这样的初学者很好的解释 (4认同)

pol*_*ara 23

所有好的答案,我必须补充:

既然TRUNCATE TABLE是DDL(数据定义语言),而不是DML(Data Manipulation Langauge)命令,Delete Triggers则不运行.


Sha*_*r K 19

删除Vs摘要在SQL服务器中截断
完整文章请点击此链接:http://codaffection.com/sql-server-article/delete-vs-truncate-in-sql-server/

在此输入图像描述

取自dotnet mob文章:在SQL Server中删除Vs截断


小智 17

截短

TRUNCATE SQL 查询从表中删除所有行,而不记录单个行删除。

  • TRUNCATE 是一个 DDL 命令。
  • TRUNCATE 使用表锁执行,并锁定整个表以删除所有记录。
  • 我们不能将 WHERE 子句与 TRUNCATE 一起使用。
  • TRUNCATE 从表中删除所有行。
  • 事务日志中的日志记录最少,因此性能更快。
  • TRUNCATE TABLE 通过取消分配用于存储表数据的数据页来删除数据,并仅在事务日志中记录页取消分配。
  • 要在表上使用 Truncate,您至少需要对该表具有 ALTER 权限。
  • Truncate 使用的事务空间比 Delete 语句少。
  • 截断不能与索引视图一起使用。
  • TRUNCATE 比 DELETE 快。

删除

要执行 DELETE 队列,需要对目标表具有删除权限。如果您需要在 DELETE 中使用 WHERE 子句,则还需要选择权限。

  • DELETE 是 DML 命令。
  • DELETE 使用行锁执行,表中的每一行都被锁定以进行删除。
  • 我们可以使用 where 子句和 DELETE 来过滤和删除特定的记录。
  • DELETE 命令用于根据 WHERE 条件从表中删除行。
  • 它维护日志,所以它比 TRUNCATE 慢。
  • DELETE 语句一次删除一行,并在事务日志中为每个删除的行记录一个条目。
  • 列的标识保留 DELETE 保留标识。
  • 要使用删除,您需要对表具有 DELETE 权限。
  • Delete 比 Truncate 语句使用更多的事务空间。
  • 删除可以与索引视图一起使用。


mat*_*ieu 16

对于SQL Server或MySQL,如果存在具有自动增量的PK,则truncate将重置计数器.


Wal*_*tty 12

"截断不记录任何东西"是正确的.我走得更远:

截断不在事务的上下文中执行.

truncate over delete的速度优势应该是显而易见的.根据您的具体情况,这种优势从琐碎到巨大.

但是,我看到truncate无意中破坏了引用完整性,并违反了其他约束.通过修改事务外部数据而获得的权力必须与您在没有网络的情况下走钢丝时所承担的责任相平衡.


Sac*_*iya 7

TRUNCATE是DDL语句,DELETE而是DML语句.以下是两者之间的差异:

  1. TRUNCATEDDL(数据定义语言)语句一样,它不需要提交来使更改成为永久更改.这就是为什么truncate删除的行无法回滚的原因.另一方面DELETE,DML(数据操作语言)语句因此需要显式提交以使其效果永久化.

  2. TRUNCATE始终从表中删除所有行,使表保持空,表结构保持不变,DELETE但如果使用where子句,则可以有条件地删除.

  3. TRUNCATE TABLE无法恢复由语句删除的行,也无法在语句中指定where子句TRUNCATE.

  4. TRUNCATE语句不会触发触发器,而不是触发DELETE语句上的delete触发器

是与该主题相关的非常好的链接.


DCo*_*kie 6

是的,DELETE较慢,TRUNCATE更快.为什么?

DELETE必须读取记录,检查约束,更新块,更新索引以及生成重做/撤消.所有这些都需要时间.

TRUNCATE只是调整数据库中的表格(高水位线)和噗!数据消失了.

这是Oracle特定的,AFAIK.


wpz*_*e4u 5

如果意外地使用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从表中删除了所有数据.您可以回滚已提交的事务.恢复上次备份并运行事务日志,直到删除/截断即将发生.


小智 5

这是我对SQL Server 中 DELETE 和 TRUNCATE 之间区别的详细回答

删除数据 :首先,两者都可用于从表中删除行。
但是 DELETE 不仅可用于从 Table 中删除行,还可以从 VIEW 或 OPENROWSET 或 OPENQUERY 的结果中删除行,这些行取决于提供者功能。

FROM 子句:使用DELETE,您还可以使用另一个FROM 子句根据另一个表中的行从一个表/视图/rowset_function_limited 中删除行。在那个 FROM 子句中,您还可以编写正常的 JOIN 条件。实际上,您可以通过将 SELECT 替换为 DELETE 并删除列名,从不包含任何聚合函数的 SELECT 语句创建 DELETE 语句。
使用 TRUNCATE,您不能这样做。

WHERE:TRUNCATE 不能有 WHERE 条件,但 DELETE 可以。这意味着使用 TRUNCATE 您不能删除特定行或特定行组。TRUNCATE TABLE 类似于没有 WHERE 子句的 DELETE 语句。

性能:TRUNCATE TABLE 速度更快,使用的系统和事务日志资源更少。原因之一是任一语句使用的锁。DELETE 语句使用行锁执行,表中的每一行都被锁定以进行删除。TRUNCATE TABLE 总是锁定表和页,但不是每一行。

事务日志:DELETE 语句一次删除一行,并在事务日志中为每一行创建单独的条目。
TRUNCATE TABLE 通过取消分配用于存储表数据的数据页来删除数据,并仅在事务日志中记录页取消分配。

:执行DELETE 语句后,表中仍可以包含空页。TRUNCATE 通过取消分配用于存储表数据的数据页来删除数据。

触发器:TRUNCATE 不会激活表上的删除触发器。所以在使用 TRUNCATE 时必须非常小心。如果在表上定义了删除触发器以在删除行时执行一些自动清理或日志记录操作,则永远不应使用 TRUNCATE。

标识列:如果表包含标识列,则使用TRUNCATE,该列的计数器将重置为为该列定义的种子值。如果未定义种子,则使用默认值 1。DELETE 不会重置身份计数器。因此,如果您想保留身份计数器,请改用 DELETE。

复制:DELETE 可用于事务复制或合并复制中使用的表。
而 TRUNCATE 不能用于事务复制或合并复制中涉及的表。

回滚:DELETE 语句可以回滚。
如果 TRUNCATE 包含在 TRANSACTION 块中并且会话未关闭,则它也可以回滚。一旦会话关闭,您将无法回滚 TRUNCATE。

限制:如果DELETE 语句违反触发器或试图删除另一个表中具有FOREIGN KEY 约束的数据所引用的行,则它可能会失败。如果 DELETE 删除多行,并且删除的行中的任何一行违反触发器或约束,则语句被取消,返回错误,并且不删除任何行。
如果对视图使用 DELETE,则该视图必须是可更新视图。TRUNCATE 不能用于索引视图中使用的表。
TRUNCATE 不能用于 FOREIGN KEY 约束引用的表,除非表具有引用自身的外键。