优点& TRUNCATE与DELETE FROM的缺点

时间:2010-07-15 14:01:14

标签: sql-server sql-server-2008 tsql sql-delete truncate

有人可以让我快速概述使用以下两个陈述的利弊:

TRUNCATE TABLE dbo.MyTable

VS

DELETE FROM dbo.MyTable

似乎他们在完成所有事情时都做同样的事情;但这两者之间是否存在差异。

12 个答案:

答案 0 :(得分:83)

TRUNCATE不生成任何回滚数据,这使得它快速闪电。它只是释放表格使用的数据页面。

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

修改 请注意,上述内容对于SQL Server不正确(但它适用于Oracle)。在SQL Server中,如果您在事务内并且尚未提交事务,则可以回滚截断操作。从SQL Server的角度来看,DELETE FROM和TRUNCATE之间的一个关键区别是this: “DELETE语句一次删除一行,并在事务日志中为每个已删除的行记录一个条目.TRUNCATE TABLE通过释放用于存储表数据的数据页来删除数据,并仅在事务日志中记录页面解除分配。 “

换句话说,在TRUNCATE期间记录的次数较少,因为只有页面解除分配记录在事务日志中,而每次删除行都会记录删除行。这是TRUNCATE快速闪电的原因之一。

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

编辑2: 另一个关键点是TRUNCATE TABLE会将您的身份重置为初始种子,而DELETE FROM将从它停止的位置继续递增。 参考:本罗宾逊的答案。

答案 1 :(得分:46)

其他答案中未提及的另一个要点是TRUNCATE TABLE 身份重置初始种子,而DELETE FROM将携带从它停止的地方开始递增。

答案 2 :(得分:8)

与安全性角度的另一个区别是TRUNCATE需要对表具有ALTER权限,而DELETE仅需要(滚动)对该表的DELETE权限。

答案 3 :(得分:4)

TRUNCATE TABLE不记录交易。这意味着它对于大型桌子来说是快速的。缺点是您无法撤消操作。

DELETE FROM记录事务日志中正在删除的每一行,因此操作需要一段时间,并导致事务日志急剧增长。好处是你可以根据需要撤消操作。

答案 4 :(得分:3)

删除Vs概述在SQL服务器中截断

对于完整文章,请在此连接后:Delete Vs Truncate in SQL Server

enter image description here

/*Truncate - Syntax*/
TRUNCATE TABLE table_name

/*Delete - Syntax*/
DELETE FROM table_name
WHERE some_condition

答案 5 :(得分:2)

我认为只有在操作和显式事务中执行时才能回滚Delete和Truncate。否则,您必须执行还原以恢复已删除的数据

答案 6 :(得分:1)

根本区别在于它们的记录方式。 DELETE和TRUNCATE的记录方式不同,但两者都可以完全相同的方式回滚。记录所有更改数据的操作。在SQL Server中,没有非记录操作。

答案 7 :(得分:0)

有一件事非常重要(imo)而其他答案中没有提到的是Speech需要架构稳定性锁定TRUNCATE,而Sch-S使用行锁。让我们检查以下内容:

DELETE

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

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;

请注意,我使用了SELECT COUNT(*) FROM TABLE_A (NOLOCK) 子句。您认为现在会发生什么?此查询将等待5个小时。为什么?因为NOLOCK子句需要NOLOCK锁定Sch-S,但TABLE_A子句已经TRUNCATE。由于我们尚未提交事务,因此即使在Sch-S子句之后锁仍然存在。 TRUNCATE锁定表基本上意味着通过添加/删除列等来改变Sch-S或者它被截断。您甚至无法执行以下内容:

TABLE_A

这也将停留5个小时。但是,如果您将SELECT object_id('TABLE_A') 替换为TRUNCATE,您会发现表格上没有DELETE FROM锁,并且上述查询不会被卡住。

答案 8 :(得分:0)

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

例如:

DELETE FROM table_name;

最终会出错:

  

Msg 3314,Level 21,State 3,Line 1

     

在撤消数据库' ...'中记录的操作期间,日志记录ID()发生错误。通常,以前将特定故障记录为Windows事件日志服务中的错误。从备份还原数据库或文件,或修复数据库。

     

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

     

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

虽然TRUNCATE可行:

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

答案 9 :(得分:0)

加上所有答案,还要考虑一下Truncate不会触发表的delete trigger,但是delete语句将触发表的delete trigger每行。

答案 10 :(得分:-1)

$connection = $this->getEntityManager()->getConnection();
$connection->exec("Truncate TABLE <tablename>;");

答案 11 :(得分:-2)

truncate不执行任何日志记录,删除操作,所以如果你有大量的记录,你的trans日志是巨大的