如果我Temp Tables
是在存储过程的定义中创建的,然后dropping them when I am done
使用它们会导致重新编译执行计划吗?
对于每次调用的存储过程?有什么亲身经历吗?请问有什么解释吗?
就像在每次调用结束时删除临时表一样,执行计划变得无效。SQL Server 是否仍然保留执行计划并在下一次调用时重用,还是在每次调用时重新编译它。
如果我Temp Tables
是在存储过程的定义中创建的,然后dropping them when I am done
使用它们会导致重新编译执行计划吗?
对于每次调用的存储过程?有什么亲身经历吗?请问有什么解释吗?
就像在每次调用结束时删除临时表一样,执行计划变得无效。SQL Server 是否仍然保留执行计划并在下一次调用时重用,还是在每次调用时重新编译它。
删除临时表并不重要。如果创建了表(永久或临时),则重新编译该语句之后的所有语句(即使它们不引用该表)。使用 EXEC 调用可执行对象不会重新编译。这是因为 SQL Server 可以在创建对象后创建计划。(在这种情况下,临时表。)
您可以使用扩展事件及其 sql_statement_recompile 或 SQL Trace / SQL Server Profiler SQL:StmtRecompile 监视重新编译。
不是重新编译整个过程,而是重新编译单个语句。
一般来说,存储过程中的任何 DDL 都会导致重新编译,然后如果您使用创建和删除表指令,您将获得重新编译。可以通过将 DDL 作为存储过程中的第一条语句来缓解这种情况,但您应该在之前进行测试并在服务器中亲眼看到它。
如果您必须放入时态表中的数据集很小并且您不需要非唯一索引,则应尝试使用表变量来代替。将太多行放在表变量中不是一个好主意,因为它们没有统计信息,Sql Server 总是“认为”它们只有一条记录,并且查询计划可能比最佳记录有点远(但它会避免由于临时表创建而重新编译)。
临时表可能会导致重新编译。发生这种情况只是因为 SQL Server 引擎将它们视为常规表。当表(基础查询所依赖的)发生显着变化时,SQL Server 会检测到这种变化(使用自动更新统计信息)并标记要重新编译的依赖查询,以便下次执行可以创建最佳执行计划。
一旦临时表或依赖于临时表的查询发生更改,查询引擎将无法执行相同的缓存计划,因为它无法容纳查询。
应该注意的是,表变量本身不会导致重新编译。在某些情况下,这些可能是更好的选择。
有关临时表重新编译的更多信息,请参阅http://sqlserverplanet.com/optimization/temp-table-recompiles
。