计划缓存行为

use*_*729 2 sql-server database-internals sql-server-2012

有人可以解释一下为什么以下内容没有被缓存

use AdventureWorks2014
go
DECLARE @id INT=43865
SELECT
sp.[BusinessEntityID]
, so.salesorderid
FROM sales.salesorderheader so JOIN sales.salesperson sp
ON sp.[BusinessEntityID] = so.salespersonid
WHERE so.salesorderid = @id
Run Code Online (Sandbox Code Playgroud)

每次我使用不同的参数执行上述查询时,它都会在计划缓存中创建一个条目

顺便说一下,优化临时工作负载已设置

谢谢

Aar*_*and 8

您使用的是局部变量,而不是参数。所以因为这是您的查询文本的一部分:

DECLARE @id INT=43865
Run Code Online (Sandbox Code Playgroud)

它作为查询散列的一部分包含在内(将查询文本,包括43865,转换为二进制),因此每次更改文本时都会生成不同的散列。这就是它在 Management Studio 查询窗口中的工作方式,但例如,如果您从 C# 应用程序发送正确参数化的即席查询,则可能会有所不同。

您可以尝试将数据库设置更改Parameterization为强制,但这有点像用推土机杀死蚊子。更好的是(恕我直言),而不是临时 SQL,使用存储过程,@id通过适当的参数传递局部变量的值(或完全跳过局部变量,直接将 43865 传递给存储过程参数)。

Kendra Little 也写了一些关于这个的文章,她建议使用#temporary 程序来模拟您的实际程序(例如,在不更改基本程序的情况下测试更改)。但这只有在您首先已经有一个存储过程时才相关: