一尘不染

为什么同时使用 TRUNCATE 和 DROP?

sql

在我工作的系统中,有很多使用临时表的存储过程和 SQL 脚本。使用这些表后,最好删除它们。

我的许多同事(几乎所有人都比我更有经验)通常这样做:

TRUNCATE TABLE #mytemp
DROP TABLE #mytemp

DROP TABLE我通常在我的脚本中使用一个。

TRUNCATE在 a之前立即执行 a 有什么好的理由DROP吗?


阅读 102

收藏
2022-10-25

共1个答案

一尘不染

TRUNCATE并且DROP在行为和速度上几乎相同,因此根本不需要在 aTRUNCATE之前执行正确的操作。DROP


注意:我从 SQL Server 的角度编写了这个答案,并假设它同样适用于 Sybase。看来,情况并非完全如此

注意:当我第一次发布这个答案时,还有其他几个评价很高的答案 - 包括当时接受的答案 - 提出了几个虚假声明,例如:TRUNCATE未记录;TRUNCATE无法回滚;TRUNCATEDROP;快 等等

既然已经清理了这个线程,那么接下来的反驳似乎与原始问题相切。我把它们留在这里作为其他人想要揭穿这些神话的参考。


有一些流行的谎言——甚至在有经验的 DBA 中也很普遍——可能促成了这种TRUNCATE-then-DROP模式。他们是:

  • 误区TRUNCATE没有记录,因此无法回滚。
  • 误区TRUNCATEDROP

让我反驳这些谎言。我是从 SQL Server 的角度写这篇反驳文章的,但我在这里所说的一切都应该同样适用于 Sybase。

TRUNCATE 记录,并且可以回滚。

  • TRUNCATE是一个记录的操作,所以它*可以*回滚只需将其包装在事务中即可。

```sql
USE [tempdb];
SET NOCOUNT ON;

CREATE TABLE truncate_demo (
whatever VARCHAR(10)
);

INSERT INTO truncate_demo (whatever)
VALUES (‘log this’);

BEGIN TRANSACTION;
TRUNCATE TABLE truncate_demo;
ROLLBACK TRANSACTION;

SELECT * FROM truncate_demo;

DROP TABLE truncate_demo;
```

但是请注意,不适用于 Oracle。尽管由 Oracle 的撤消和重做功能记录和保护,但TRUNCATE其他 DDL 语句不能由用户回滚,因为 Oracle在所有 DDL 语句之前和之后立即发出隐式提交。

  • TRUNCATE是最小记录,而不是完全记录。这意味着什么?说你TRUNCATE一张桌子。无需将每个已删除的行都放入事务日志中,TRUNCATE只需将它们所在的数据页标记为未分配。这就是为什么它这么快。这也是您无法TRUNCATE使用日志阅读器从事务日志中恢复 -ed 表的行的原因。您会发现所有这些都是对已释放数据页的引用。

将此与DELETE. 如果您DELETE将表中的所有行都提交并提交事务,理论上您仍然可以在事务日志中找到已删除的行并从那里恢复它们。那是因为DELETE将每个已删除的行写入事务日志。对于大型表,这将使其比TRUNCATE.

DROP与 TRUNCATE 一样快。

  • TRUNCATE,DROP是一个最少记录的操作。 这意味着DROP也可以回滚。这也意味着它的工作方式TRUNCATE. DROP将相应的数据页标记为未分配,并将表的元数据标记为已删除,而不是删除单个行。

  • 因为TRUNCATEDROP工作方式完全相同,它们运行速度一样快。 在-ing 表格之前-ing 表格是没有意义的。TRUNCATE``DROP如果您不相信我,请在您的开发实例上运行此演示脚本。

在我的本地机器上,有一个温暖的缓存,我得到的结果如下:

```sql
table row count: 134,217,728

run# transaction duration (ms)
TRUNCATE TRUNCATE then DROP DROP
==========================================
01 0 1 4
02 0 39 1
03 0 1 1
04 0 2 1
05 0 1 1
06 0 25 1
07 0 1 1
08 0 1 1
09 0 1 1
10 0 12 1


avg 0 8.4 1.3
```

因此,对于一个 1.34亿行的表来说DROPTRUNCATE实际上根本不需要任何时间。(在冷缓存上,第一次或两次运行大约需要 2-3 秒。)我还认为TRUNCATEthenDROP操作的平均持续时间较高是由于我本地机器上的负载变化,而不是因为这种组合在某种程度上是神奇的比单个操作差一个数量级。毕竟,它们几乎完全相同。

2022-10-25