有人可以让我快速概述使用以下两个陈述的利弊:
TRUNCATE TABLE dbo.MyTable
VS
DELETE FROM dbo.MyTable
似乎他们在完成所有事情时都做同样的事情;但这两者之间是否存在差异。
答案 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
/*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)
DELETE
与TRUNCATE
之间的另一个区别是表格损坏时的行为。
例如:
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日志是巨大的