删除或不删除存储过程中的临时表

Dmi*_*sev 9 sql-server stored-procedures temp-tables

我多次看到这个问题,但我找不到让我满意的答案。基本上人们和书籍所说的是“虽然临时表在超出范围时会被删除,但您应该在不再需要它们时显式删除它们以减少服务器上的资源需求”。

我很清楚,当您在管理工作室工作并创建表时,在关闭窗口或断开连接之前,您将使用该表的一些资源,从逻辑上讲,最好删除它们。

但是当你使用过程时,如果你想清理表,你很可能会在它真正结束时这样做(我不是在谈论当你真的不需要它时你立即删除表的情况程序)。所以工作流程是这样的:

当您投入 SP 时:

  • SP执行开始
  • 做一些事情
  • 删除表
  • 执行结束

据我所知,当你不放弃时它怎么可能工作:

  • SP执行开始
  • 做一些事情
  • 执行结束
  • 删除表

这里有什么区别?我只能想象需要一些资源来识别临时表。还有其他想法吗?

更新:

我用 2 个 SP 进行了简单的测试:

create procedure test  as
begin
create table #temp (a int)
insert into #temp values (1);
drop table #temp;
end
Run Code Online (Sandbox Code Playgroud)

另一个没有 drop 语句。我启用了用户统计并运行了测试:

declare @i int = 0;
 while @i < 10000
 begin
 exec test;
 SET @i= @i + 1;
 end
Run Code Online (Sandbox Code Playgroud)

这就是我所拥有的(在SP中试用1-3掉落表,4-6不掉落) 在此处输入图片说明

如图所示,当我不删除临时表时,所有统计数据都相同或有所减少。

更新2:

我第二次运行了这个测试,但现在有 10 万次调用,并且还添加了 SET NOCOUNT ON。这些是结果: 在此处输入图片说明

由于第二次运行确认,如果您不删除 SP 中的表,那么您实际上节省了一些用户时间,因为这是由其他一些内部进程完成的,但在用户时间之外。

sep*_*pic 6

您可以在 Paul White 的这篇文章中阅读更多信息:存储过程中的临时表

创建和删除,不要

我将在下一篇文章中更详细地讨论这一点,但关键是 CREATE TABLE 和 DROP TABLE 不会在存储过程中创建和删除临时表,前提是可以缓存临时对象。 临时对象在执行 DROP TABLE 时被重命名为内部形式,并在下次执行时遇到 CREATE TABLE 时重命名回相同的用户可见名称。此外,还会缓存在临时表上自动创建的任何统计信息。这意味着下一次调用该过程时,上次执行的统计信息仍然存在。


Xed*_*dni 1

从技术上讲,本地范围的临时表(前面有一个主题标签)将在 SPID 关闭后自动退出范围。在一些非常奇怪的情况下,您会在某个地方缓存临时表定义,然后没有真正的方法来删除它。通常,当您有一个嵌套的存储过程调用并包含同名的临时表时,就会发生这种情况。

当你使用完表后,删除它们是一个好习惯,但除非发生意外情况,否则一旦进程完成,它们就应该被取消作用域。