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 FROM
logging事务日志中要删除的每一行,这样操作需要一段时间,并且会使事务日志显着增长。 好处是如果需要的话可以撤销操作。
我相信删除和截断只能回滚,如果操作执行和显式事务。 否则,您将不得不执行还原来恢复已删除的数据
根本的区别在于它们被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-S
locking,但是TRUNCATE
子句已经在Sch-S
上了。 由于我们还没有提交事务,即使在那个TRUNCATE
子句之后,锁仍然是TRUNCATE
。 表上的Sch-S
锁基本上意味着要么通过添加/删除列等来更改TABLE_A
,要么正在被截断。 你甚至不能执行如下所示:
SELECT object_id('TABLE_A')
这也将持续5个小时。 但是,如果使用DELETE FROM
replace该TRUNCATE
,则会看到表上没有Sch-S
锁,上面的查询将不会被删除。
DELETE
和TRUNCATE
之间的另一个区别是当表损坏时的行为。
例如:
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日志是巨大的