我们在 SQL Server 2019 上有一个数据库,兼容性设置为 110(SQL Server 2012)。我们有一个经常重新编译的存储过程,我注意到我们正在使用许多临时表。我们创建一个临时表,插入数据,然后在其上添加索引以供进一步查询。我怀疑这可能会导致重新编译。临时表会触发重新编译吗?如果会,在什么条件下?谢谢!
我们在 SQL Server 2019 上有一个数据库,兼容性设置为 110(SQL Server 2012)。我们有一个经常重新编译的存储过程,我注意到我们正在使用许多临时表。我们创建一个临时表,插入数据,然后在其上添加索引以供进一步查询。我怀疑这可能会导致重新编译。临时表会触发重新编译吗?如果会,在什么条件下?谢谢!
重新编译存储过程文档说:
此外,SQL Server 2012 中的计划缓存和重新编译白皮书指出:
因此,罪魁祸首不是临时表本身,而是对其模式所做的改变。
场景 1(无 #temp 表缓存)
按照 SQL Server 2012 中的计划缓存和重新编译白皮书中的描述跟踪编译事件,每次执行都显示完全相同的情况。
在上述情况下,
#temp
每次执行时,表在执行开始时都不存在。因此,所有引用它的语句都将接受延迟编译,并在首次执行之前立即进行编译。如果您只是线性地流经这些语句,那么这是由于#temp
表使用本身而导致的唯一重新编译原因。我在上面添加了一个 GOTO,以使事情变得更有趣,并显示索引创建后第一个 SELECT 语句的第二次重新编译。场景 2(使用 #temp 表缓存)
与第一个过程相比,显著的变化是没有单独的
CREATE INDEX
语句。这意味着如果 SQL Server 决定这样做,该#temp
表就有资格使用临时表缓存(因为这是本例中唯一的阻塞问题)(在我的开发机器上,这确实需要几次尝试才能看到,因为我的本地 SQL Server 内存有点不足)。当没有重新使用缓存的临时表时,它会显示通常的延迟编译模式。跟踪中粉红色突出显示的区域显示了一次执行,其中它重新使用了缓存的临时表,并且没有重新编译事件。但这并不意味着与表相关的重新编译事件将始终为零#temp
。您仍然可以看到常见的其他重新编译原因,例如“统计信息已更改” - 尽管在缓存临时表的情况下这如何工作可能会有问题。