在我工作的系统中,有很多使用临时表的存储过程和 SQL 脚本。使用这些表后,最好删除它们。
我的许多同事(几乎所有人都比我更有经验)通常这样做:
TRUNCATE TABLE #mytemp DROP TABLE #mytemp
DROP TABLE我通常在我的脚本中使用一个。
DROP TABLE
TRUNCATE在 a之前立即执行 a 有什么好的理由DROP吗?
TRUNCATE
DROP
TRUNCATE并且DROP在行为和速度上几乎相同,因此根本不需要在 aTRUNCATE之前执行正确的操作。DROP
注意:我从 SQL Server 的角度编写了这个答案,并假设它同样适用于 Sybase。看来,情况并非完全如此。
注意:当我第一次发布这个答案时,还有其他几个评价很高的答案 - 包括当时接受的答案 - 提出了几个虚假声明,例如:TRUNCATE未记录;TRUNCATE无法回滚;TRUNCATE比DROP;快 等等
既然已经清理了这个线程,那么接下来的反驳似乎与原始问题相切。我把它们留在这里作为其他人想要揭穿这些神话的参考。
有一些流行的谎言——甚至在有经验的 DBA 中也很普遍——可能促成了这种TRUNCATE-then-DROP模式。他们是:
TRUNCATE-then-DROP
让我反驳这些谎言。我是从 SQL Server 的角度写这篇反驳文章的,但我在这里所说的一切都应该同样适用于 Sybase。
```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 语句之前和之后立即发出隐式提交。
将此与DELETE. 如果您DELETE将表中的所有行都提交并提交事务,理论上您仍然可以在事务日志中找到已删除的行并从那里恢复它们。那是因为DELETE将每个已删除的行写入事务日志。对于大型表,这将使其比TRUNCATE.
DELETE
像TRUNCATE,DROP是一个最少记录的操作。 这意味着DROP也可以回滚。这也意味着它的工作方式与TRUNCATE. DROP将相应的数据页标记为未分配,并将表的元数据标记为已删除,而不是删除单个行。
因为TRUNCATE和DROP工作方式完全相同,它们运行速度一样快。 在-ing 表格之前-ing 表格是没有意义的。TRUNCATE``DROP如果您不相信我,请在您的开发实例上运行此演示脚本。
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亿行的表来说DROP,TRUNCATE实际上根本不需要任何时间。(在冷缓存上,第一次或两次运行大约需要 2-3 秒。)我还认为TRUNCATEthenDROP操作的平均持续时间较高是由于我本地机器上的负载变化,而不是因为这种组合在某种程度上是神奇的比单个操作差一个数量级。毕竟,它们几乎完全相同。