7

如果我Temp Tables是在存储过程的定义中创建的,然后dropping them when I am done使用它们会导致重新编译执行计划吗?

对于每次调用的存储过程?有什么亲身经历吗?请问有什么解释吗?

就像在每次调用结束时删除临时表一样,执行计划变得无效。SQL Server 是否仍然保留执行计划并在下一次调用时重用,还是在每次调用时重新编译它。

4

3 回答 3

6

删除临时表并不重要。如果创建了表(永久或临时),则重新编译该语句之后的所有语句(即使它们不引用该表)。使用 EXEC 调用可执行对象不会重新编译。这是因为 SQL Server 可以在创建对象后创建计划。(在这种情况下,临时表。)

您可以使用扩展事件及其 sql_statement_recompile 或 SQL Trace / SQL Server Profiler SQL:StmtRecompile 监视重新编译。

  1. 一条语句开始执行。引发 SP:StmtStarting 或 SQL:StmtStarting
  2. 该语句被重新编译。SQL:StmtRecompile 被提出。SP:StmtStarting 或 SQL:StmtStarting 再次引发
  3. 声明完毕。引发 SP:StmtCompleted 或 SQL:StmtCompleted

不是重新编译整个过程,而是重新编译单个语句。

于 2013-10-27T20:49:37.557 回答
-2

一般来说,存储过程中的任何 DDL 都会导致重新编译,然后如果您使用创建和删除表指令,您将获得重新编译。可以通过将 DDL 作为存储过程中的第一条语句来缓解这种情况,但您应该在之前进行测试并在服务器中亲眼看到它。

如果您必须放入时态表中的数据集很小并且您不需要非唯一索引,则应尝试使用表变量来代替。将太多行放在表变量中不是一个好主意,因为它们没有统计信息,Sql Server 总是“认为”它们只有一条记录,并且查询计划可能比最佳记录有点远(但它会避免由于临时表创建而重新编译)。

于 2013-10-27T20:52:54.327 回答
-3

临时表可能会导致重新编译。发生这种情况只是因为 SQL Server 引擎将它们视为常规表。当表(基础查询所依赖的)发生显着变化时,SQL Server 会检测到这种变化(使用自动更新统计信息)并标记要重新编译的依赖查询,以便下次执行可以创建最佳执行计划。

一旦临时表或依赖于临时表的查询发生更改,查询引擎将无法执行相同的缓存计划,因为它无法容纳查询。

应该注意的是,表变量本身不会导致重新编译。在某些情况下,这些可能是更好的选择。

有关临时表重新编译的更多信息,请参阅http://sqlserverplanet.com/optimization/temp-table-recompiles

于 2013-10-28T06:59:49.937 回答