显式删除临时表或让SQL Server处理它

sca*_*cci 46 sql-server sql-server-2008-r2

处理临时表的删除的最佳做法是什么.我已经读过你应该显式处理drop以及sql server应该处理drop ....正确的方法是什么?我总是觉得你应该自己清理你在sproc中创建的临时表等等.但是,然后我找到了其他的建议.

任何见解将不胜感激.我只是担心我没有遵循我创建的临时表的最佳实践.

谢谢,

小号

Har*_*ode 26

我的观点是,首先看看你是否真的需要临时表 - 或者 - 你可以用CTE做.其次,我总是放弃临时表.有时你需要有一个作为连接的临时表(例如## temp),所以如果你第二次运行查询,并且你有明确的代码来创建临时表,你会得到一个错误,表明该表已经存在.自己清理后总是一个很好的软件实践.

  • 请注意##temp 对所有人可见(即其他连接),但会在原始会话结束时删除。 (2认同)
  • 必须在其中曾经使用过的所有临时表的存储过程的底部维护一个目录,以便可以删除它们是额外的样板,并且容易出错。只有在必要时才进行自我清理是一种很好的软件实践,这样做并不会降低整个过程的效率。总是在不了解目的和上下文并且不知道是否有更好的方法的情况下做某事,这使我们变得臃肿而难以维护代码。清理,作为一项消耗资源的任务,也不例外。 (2认同)

Ved*_*ran 9

当超出范围时,本地临时表(名称中的单个#)将自动删除,因此如果范围是短暂的(例如存储过程),则显式删除是没有意义的.

  • 参考:https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql --“临时表超出范围时会自动删除,除非明确删除using DROP TABLE”——“存储过程完成时,在存储过程中创建的本地临时表将自动删除。创建该表的存储过程执行的任何嵌套存储过程都可以引用该表。” (2认同)
  • *超出范围时将自动删除* - 这足够准确吗?“超出范围”也可能意味着“在查询编辑器窗口中按 F5 后脚本已完成执行”,在这种情况下,临时表仍然存在。@kol 的链接文章特别指出:“所有其他本地临时表都会在当前会话结束时自动删除”,这比简单地“超出范围”要具体得多。 (2认同)

小智 5

我曾经属于让后台服务器进程清理对象的人群,但是,最近遇到的 TempDB 日志文件极端增长的问题改变了我的看法。我不确定每个版本的 SQL Server 是否都存在这种情况,但自从迁移到 SQL 2016 并将驱动器放在 PureStorage SSD 阵列上后,运行情况有所不同。进程通常受 CPU 限制而不是 I/O 限制,并且显式删除临时对象不会导致日志增长出现问题。虽然我没有深入探究原因,但我怀疑它与 .NET 世界中的垃圾收集没有什么不同,在 .NET 世界中,显式调用时它是同步的,而留给系统时是异步的。这很重要,因为显式删除将释放日志文件中的存储,并使其在下一次日志备份时可用,而当不显式删除对象时,情况似乎并非如此。在大多数系统上,这可能不是一个大问题,但在支持大量 ERP 和 Web 店面且具有许多并发事务和大量 TempDB 使用的系统上,它会产生很大的影响。至于为什么首先要创建 TempDB 对象,由于大多数查询中的数据量很大,无论如何它都会溢出到 TempDB 存储中,因此创建具有必要索引的对象通常比让系统自动处理。