SQL中的TRUNCATE
和DELETE
有什么区别?
如果您的答案是特定于平台的,请说明。
这是一个差异列表。我已经强调了Oracle特有的功能,希望社区也可以添加其他供应商的特定差异。大多数供应商常见的差异可以直接在标题下方,下面突出显示差异。
如果你想快速删除表中的所有行,并且你确实想要这样做,并且你没有对表的外键,那么TRUNCATE可能会比DELETE更快。
必须考虑各种系统特定问题,详情如下。
删除是DML,Truncate是DDL(What is DDL and DML?)
供应商可变
SQL *服务器
截断可以回滚。
PostgreSQL的
截断可以回滚。
神谕
因为TRUNCATE是DDL,所以它涉及两个提交,一个在语句执行之前,一个在语句执行之后。因此,Truncate不能回滚,并且truncate进程中的失败无论如何都会发出提交。
但是,请参阅下面的Flashback。
删除不会恢复空间,Truncate会恢复空间
神谕
如果使用REUSE STORAGE子句,则不会取消分配数据段,如果要重新装入数据表,则可以稍微提高效率。高水位标记被重置。
删除可用于删除所有行或仅删除行的子集。截断删除所有行。
神谕
对表进行分区时,可以单独截断各个分区,从而可以部分删除所有表的数据。
删除可以应用于群集内的表和表。截断仅适用于表或整个群集。 (可能是Oracle特定的)
神谕
删除不会影响数据对象ID,但truncate会分配一个新的数据对象id,除非从创建以来从未对表进行过插入即使回滚的单个插入也会导致在截断时分配新的数据对象id 。
闪回可以跨删除工作,但截断可以防止闪回到操作之前的状态。
但是,从11gR2开始,FLASHBACK ARCHIVE功能允许这样,除了Express Edition
Use of FLASHBACK in Oracle 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;
如果意外地使用Delete / Truncate从表中删除了所有数据。您可以回滚已提交的事务。恢复上次备份并运行事务日志,直到删除/截断即将发生。
以下相关信息来自a blog post:
在处理数据库时,我们使用Delete和Truncate而不知道它们之间的差异。在本文中,我们将讨论Sql中Delete和Truncate之间的区别。
删除:
- 删除是DML命令。
- 使用行锁执行Delete语句,表中的每一行都被锁定以进行删除。
- 我们可以在where子句中指定过滤器。
- 如果条件存在,它将删除指定的数据。
- 将活动删除为触发器,因为操作是单独记录的。
- 比Truncate慢,因为它保留了日志
截短
- Truncate是一个DDL命令。
- 截断表总是锁定表和页,但不是每行。因为它删除了所有数据。
- 不能使用Where条件。
- 它删除所有数据。
- 截断表无法激活触发器,因为该操作不会记录单个行删除。
- 性能更快,因为它不保留任何日志。
注意:与Transaction一起使用时,可以回滚Delete和Truncate。如果Transaction已完成,则意味着我们无法回滚Truncate命令,但我们仍然可以从Log文件回滚Delete命令,因为删除写入将它们记录在Log文件中,以防将来需要从日志文件回滚。
如果您有一个外键约束引用您尝试截断的表,即使引用表中没有数据,这也不起作用。这是因为外键检查是使用DDL而不是DML完成的。这可以通过暂时禁用表的外键约束来解决。
删除表是记录的操作。因此,每行的删除都会记录在事务日志中,这会使其变慢。截断表还删除表中的所有行,但它不会记录每行的删除,而是记录表的数据页的重新分配,这使得它更快。
〜如果意外地使用Delete / Truncate从表中删除了所有数据。您可以回滚已提交的事务。恢复上次备份并运行事务日志,直到删除/截断即将发生。
在SQL Server 2005中,我相信您可以回滚截断
如果包含在事务中,则可以回滚TRUNCATE。
请参阅以下两个参考资料并自行测试: -
TRUNCATE与DELETE是SQL访谈中臭名昭着的问题之一。只要确保你向面试官正确解释它,否则它可能会让你失去工作。问题是没有多少人知道所以如果你告诉他们YES Truncate可以回滚,他们很可能会认为答案是错误的。
DELETE
DELETE命令用于从表中删除行。 WHERE子句可用于仅删除某些行。如果未指定WHERE条件,则将删除所有行。执行DELETE操作后,您需要COMMIT或ROLLBACK事务以使更改成为永久更改或撤消它。请注意,此操作将导致触发表上的所有DELETE触发器。
TRUNCATE
TRUNCATE从表中删除所有行。无法回滚操作,也不会触发任何触发器。因此,TRUCATE更快,并且不使用与DELETE一样多的撤消空间。
DROP
DROP命令从数据库中删除表。所有表的行,索引和权限也将被删除。不会触发任何DML触发器。该操作无法回滚。
DROP和TRUNCATE是DDL命令,而DELETE是DML命令。因此,可以回滚(撤消)DELETE操作,而无法回滚DROP和TRUNCATE操作。
来自:http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands
对原始答案的小校正 - 删除也会产生大量重做(因为撤消本身受重做保护)。这可以从autotrace输出中看出:
SQL> delete from t1;
10918 rows deleted.
Elapsed: 00:00:00.58
Execution Plan
----------------------------------------------------------
0 DELETE STATEMENT Optimizer=FIRST_ROWS (Cost=43 Card=1)
1 0 DELETE OF 'T1'
2 1 TABLE ACCESS (FULL) OF 'T1' (TABLE) (Cost=43 Card=1)
Statistics
----------------------------------------------------------
30 recursive calls
12118 db block gets
213 consistent gets
142 physical reads
3975328 redo size
441 bytes sent via SQL*Net to client
537 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
10918 rows processed
这是我对the difference between DELETE and TRUNCATE in SQL Server的详细解答
•删除数据:首先,两者都可用于从表中删除行。 但DELETE可用于不仅从表中删除行,还可以从VIEW或OPENROWSET或OPENQUERY的结果中删除行,这些行受提供程序功能的限制。
•FROM子句:使用DELETE,您还可以使用另一个FROM子句,根据另一个表中的行从一个表/ view / 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。会话关闭后,您将无法回滚TRUNCATE。
•限制:如果DELETE语句违反了触发器或尝试删除具有FOREIGN KEY约束的另一个表中的数据引用的行,则DELETE语句可能会失败。如果DELETE删除多行,并且任何一个删除的行违反了触发器或约束,则会取消该语句,并返回错误,并且不会删除任何行。 如果对View使用DELETE,则该View必须是可更新视图。 TRUNCATE不能用于索引视图中使用的表。 TRUNCATE不能用于FOREIGN KEY约束引用的表,除非具有引用其自身的外键的表。
DELETE语句:此命令仅根据where子句中给出的条件从表中删除行,如果未指定条件,则从表中删除所有行。但它没有释放包含表格的空间。
SQL DELETE语句的语法是:
DELETE FROM table_name [WHERE condition];
TRUNCATE语句:此命令用于从表中删除所有行并释放包含该表的空间。
删除
DELETE is a DML command DELETE you can rollback Delete = Only Delete- so it can be rolled back In DELETE you can write conditions using WHERE clause Syntax – Delete from [Table] where [Condition]
截短
TRUNCATE is a DDL command You can't rollback in TRUNCATE, TRUNCATE removes the record permanently Truncate = Delete+Commit -so we can't roll back You can't use conditions(WHERE clause) in TRUNCATE Syntax – Truncate table [Table]
有关详细信息,请访问
http://www.zilckh.com/what-is-the-difference-between-truncate-and-delete/
这两个操作的另一个区别是,如果表包含标识列,则该列的计数器将在TRUNCATE下重置1(或者为列定义的种子值)。 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) |
+----------------------------------------+----------------------------------------------+
简而言之,truncate不会记录任何内容(因此更快但无法撤消),而删除则被记录(并且可以是更大事务的一部分,将回滚等)。如果你在dev中的表中有你不想要的数据,通常最好截断,因为你没有冒充填事务日志的风险
它很方便的一个重要原因是,您需要刷新数百万行表中的数据,但不想重建它。 “删除*”需要永远,而截断的性能影响可以忽略不计。
无法通过dblink执行DDL。
我会评论matthieu的帖子,但我还没有代表......
在MySQL中,自动增量计数器通过truncate重置,但不能通过delete重置。
并不是truncate不会在SQL Server中记录任何内容。 truncate不记录任何信息,但它记录了解除TRUNCATE的表的数据页面的重新分配。
如果我们在开始时定义事务并且我们可以在回滚后恢复截断的记录,则截断记录可以回滚。但是在提交的截断事务之后无法从事务日志备份中恢复截断的记录。
Truncate也可以在这里回滚示例
begin Tran
delete from Employee
select * from Employee
Rollback
select * from Employee
SQL中的截断和删除是两个命令,用于从表中删除或删除数据。虽然Sql命令本质上是基本的,但在使用它之前熟悉细节之前会产生很多麻烦。如果需要删除太多数据并且日志段不够,则可能导致命令选择不正确或者进程非常缓慢,甚至可能导致日志段爆炸。这就是为什么知道何时在SQL中使用truncate和delete命令至关重要的原因,在使用这些命令之前你应该知道截断和删除之间的差异,并且基于它们,我们应该能够找出何时DELETE是更好的选择去除应使用data或TRUNCATE来清除表。
请参阅检查click here
通过发出TRUNCATE TABLE语句,您指示SQL Server删除表中的每个记录,而不进行任何日志记录或事务处理。
DELETE语句可以使用WHERE子句删除特定记录,而TRUNCATE语句不需要任何记录并擦除整个表。重要的是,DELETE语句记录已删除的日期,而TRUNCATE语句则不记录。
微软sql服务器的另一个特点是使用delete
,您可以使用output
语句来跟踪已删除的记录,例如:
delete from [SomeTable]
output deleted.Id, deleted.Name
你不能用truncate
做到这一点。
DROP
DROP命令从数据库中删除表。所有表的行,索引和权限也将被删除。不会触发任何DML触发器。该操作无法回滚。
TRUNCATE
TRUNCATE从表中删除所有行。无法回滚操作,也不会触发任何触发器。因此,TRUCATE更快,并且不使用与DELETE一样多的撤消空间。
DELETE
DELETE命令用于从表中删除行。 WHERE子句可用于仅删除某些行。如果未指定WHERE条件,则将删除所有行。执行DELETE操作后,您需要COMMIT或ROLLBACK事务以使更改成为永久更改或撤消它。请注意,此操作将导致触发表上的所有DELETE触发器。
来自:http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands
Truncate命令用于重新初始化表,它是一个删除表的所有行的DDL命令。其中DELETE是一个DML命令,用于根据某些条件删除行或行集,如果未指定condition然后此命令将删除表中的所有行。
所有好的答案,我必须补充:
由于TRUNCATE TABLE
是DDL(Data Defination Language),而不是DML(Data Manipulation Langauge)命令,所以Delete Triggers
不会运行。
删除Vs摘要在SQL服务器中截断 有关完整文章,请点击此链接:http://codaffection.com/sql-server-article/delete-vs-truncate-in-sql-server/
取自dotnet mob文章:Delete Vs Truncate in SQL Server
对于SQL Server或MySQL,如果存在具有自动增量的PK,则truncate将重置计数器。
“截断不记录任何东西”是正确的。我走得更远:
截断不在事务的上下文中执行。
truncate over delete的速度优势应该是显而易见的。根据您的具体情况,这种优势从琐碎到巨大。
但是,我看到truncate无意中破坏了引用完整性,并违反了其他约束。通过修改事务外部数据而获得的权力必须与您在没有网络的情况下走钢丝时所承担的责任相平衡。
是的,DELETE较慢,TRUNCATE更快。为什么?
DELETE必须读取记录,检查约束,更新块,更新索引以及生成重做/撤消。所有这些都需要时间。
TRUNCATE只是调整数据库中的表格(高水位线)和噗!数据消失了。
这是Oracle特定的,AFAIK。
TRUNCATE
是DDL语句,而DELETE
是DML语句。以下是两者之间的差异:
TRUNCATE
是DDL(Data definition language)声明,因此不需要提交将更改永久化。这就是为什么truncate删除的行无法回滚的原因。另一方面,DELETE
是一个DML(Data manipulation language)语句,因此需要显式提交才能使其效果永久化。TRUNCATE
总是从表中删除所有行,将表保留为空并且表结构保持不变,而如果使用where子句,DELETE
可以有条件地删除。TRUNCATE TABLE
语句删除的行无法恢复,您无法在TRUNCATE
语句中指定where子句。TRUNCATE
语句不会触发触发器而不是DELETE
语句中的删除触发器Here是与该主题相关的非常好的链接。