TRUNCATE与DELETE FROM的优点和缺点

有人能给我一个使用以下两个陈述的优点和缺点的快速概述:

TRUNCATE TABLE dbo.MyTable 

VS

 DELETE FROM dbo.MyTable 

当所有的说法和做法看起来他们都做同样的事情; 但是两者之间肯定有区别。

TRUNCATE不会生成任何回滚数据,这使得它闪电般快速。 它只是取消分配表使用的数据页面。

但是,如果您处于事务中并希望能够“撤消”此删除,则需要使用DELETE FROM ,这可以回滚。

编辑:请注意上面是不正确的SQL Server(但它确实适用于Oracle)。 在SQL Server中,如果您在事务中并且事务尚未提交,则可以回滚截断操作。 从SQL Server的angular度来看,DELETE FROM和TRUNCATE之间的一个关键区别在于:“DELETE语句一次删除一行,并在事务日志中logging每个删除行的条目.TRUNCATE TABLE通过释放数据页面来删除数据用于存储表数据,并只logging事务日志中的页面释放。“

换句话说,TRUNCATE中的日志logging较less,因为只有页面释放logging在事务日志中,而用DELETE FROM删除每行logging。 这是TRUNCATE闪电般的原因之一。

还要注意,从MSDN链接中,您不能截断由外键约束引用的表,参与索引视图或使用事务复制或合并复制发布的表。

编辑2:另一个关键点是,TRUNCATE TABLE将重置您的身份到最初的种子,而DELETE FROM将继续增加从它离开的地方。 参考:本罗宾逊的答案。

其他答案中没有提到的另一个关键点是, TRUNCATE TABLE会将您的身份 重置 为初始种子 ,而DELETE FROM将从其离开的位置继续递增。

与安全angular度不同的另一个区别是,TRUNCATE需要表上的ALTER权限,而DELETE仅仅需要该表的DELETE权限。

TRUNCATE TABLE不logging事务。 这意味着大桌子闪电般快。 缺点是你不能撤消操作。

DELETE FROMlogging事务日志中要删除的每一行,这样操作需要一段时间,并且会使事务日志显着增长。 好处是如果需要的话可以撤销操作。

我相信删除和截断只能回滚,如果操作执行和显式事务。 否则,您将不得不执行还原来恢复已删除的数据

根本的区别在于它们被logging的方式。 DELETE和TRUNCATE会以不同的方式logging,但两者都可以以完全相同的方式回滚。 所有更改数据的操作都被logging下来。 在SQL Server中,不存在非logging操作的情况。

有一件事非常重要(imo),在其他答案中没有提及的是TRUNCATE需要Schema Stability锁Sch-S ,而DELETE使用行锁。 让我们来看看以下几点:

 BEGIN TRANSACTION; BEGIN TRY -- Truncate below will take LCK_M_SCH_S lock for TABLE_A TRUNCATE TABLE TABLE_A -- Lets say the query below takes 5 hours to execute INSERT INTO TABLE_A SELECT * FROM GIANT_TABLE (NOLOCK) END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; THROW END CATCH IF @@TRANCOUNT > 0 COMMIT TRANSACTION; 

现在假设在查询开始1-2分钟之后,假设我们尝试执行以下操作:

 SELECT COUNT(*) FROM TABLE_A (NOLOCK) 

注意我使用了NOLOCK子句。 你认为现在会发生什么? 此查询将等待5个小时。 为什么? 因为NOLOCK子句在TABLE_A上需要Sch-Slocking,但是TRUNCATE子句已经在Sch-S上了。 由于我们还没有提交事务,即使在那个TRUNCATE子句之后,锁仍然是TRUNCATE 。 表上的Sch-S锁基本上意味着要么通过添加/删除列等来更改TABLE_A ,要么正在被截断。 你甚至不能执行如下所示:

 SELECT object_id('TABLE_A') 

这也将持续5个小时。 但是,如果使用DELETE FROMreplace该TRUNCATE ,则会看到表上没有Sch-S锁,上面的查询将不会被删除。

DELETETRUNCATE之间的另一个区别是当表损坏时的行为。

例如:

 DELETE FROM table_name; 

最终会出现错误:

Msg 3314,Level 21,State 3,Line 1

在数据库“…”中撤销logging的操作期间,在日志loggingID()处发生错误。 通常,特定的故障在Windows事件日志服务中被logging为错误。 从备份还原数据库或文件,或修复数据库。

消息0,级别20,状态0,行0

当前命令发生严重错误。 如果有的话,结果应该被丢弃。

虽然TRUNCATE将工作:

 TRUNCATE TABLE table_name; -- Command(s) completed successfully. 

删除VS的大纲在SQL服务器中截断

对于Complete Article,在此连接之后: 在SQL Server中删除Vs Truncate

在这里输入图像说明

 /*Truncate - Syntax*/ TRUNCATE TABLE table_name /*Delete - Syntax*/ DELETE FROM table_name WHERE some_condition 
 $connection = $this->getEntityManager()->getConnection(); $connection->exec("Truncate TABLE <tablename>;"); 

截断没有做任何日志logging,删除,所以如果你有大量的logging,你的trans日志是巨大的