在回顾估计的执行计划创建过程时,我在 Grant Fritchey 的 SQL Server 执行计划中看到了这一部分,他提到:
生成估计执行计划的优化器不执行 T-SQL。它确实通过代数器运行语句……负责验证数据库对象的名称。由于 SQL Server 还没有执行查询,临时表还不存在。这是错误的原因。通过实际的执行计划运行同样的代码将完美地工作。
他在书中引用了这段代码:
CREATE TABLE TempTable
(
Id INT IDENTITY(1, 1)
);
INSERT INTO TempTable
DEFAULT VALUES
SELECT *
FROM TempTable;
您将收到的错误是
消息 208,级别 16,状态 1,第 7 行对象名称“TempTable”无效。
对我来说,这不是临时表,而是实际表。所以当我尝试使用临时“#”表时。我发现生成的估计执行计划没有问题。此处显示了生成的估计计划。
Create table #temp
(
ID INT IDENTITY (1,1)
)
Insert into #temp
DEFAULT VALUES
SELECT *
FROM #temp
有人可以解释为什么会有这种差异吗?不应该生成#table 吗?
Fritchey, G. (2012)。SQL Server 执行计划。美国斯普林菲尔德:Simple Talk Publishing。
在 SQL Server 2000 中,
#temp
表版本确实失败并显示消息但是,由于 SQL Server 2005 使用本地临时表编译计划,实际上会在幕后创建临时表。
您可以通过获取估计计划来了解这一点
产生类似的输出
负对象 ID 是短暂创建的对象的 ID。
tempdb.sys.tables
在生成估计计划的同时循环轮询并与随后输出的 TableID 进行比较可以显示这一点。您看到的引用临时表的语句的估计计划用途有限,但是即使向临时表添加一行也会触发语句级别的重新编译,并且在您实际执行 SQL 时可能会触发不同的计划。
此行为不适用于全局临时表或永久表。
我想这也是同样的原因