此查询是否等同于SQL Server 2008的OPTIMIZE FOR UNKNOWN?

Mic*_*art 11 sql-server sql-server-2005

我正在维护SQL Server 2005的存储过程,我希望我能在2008年使用一个允许查询提示的新功能:"OPTIMIZE FOR UNKNOWN"

似乎以下查询(为SQL Server 2005编写)估计相同的行数(即选择性),就像指定了OPTION(OPTIMIZE FOR UNKNOWN):

CREATE PROCEDURE SwartTest(@productid INT)
AS  
DECLARE @newproductid INT
SET @newproductid = @productid

SELECT ProductID 
FROM Sales.SalesOrderDetail 
WHERE ProductID = @newproductid
Run Code Online (Sandbox Code Playgroud)

此查询通过声明和设置新变量来避免参数嗅探.这真的是SQL Server 2005解决OPTIMIZE-FOR-UNKNOWN功能的问题吗?或者我错过了什么?(感谢权威链接,答案或测试结果).

更多信息:对SQL Server 2008的快速测试告诉我,此查询中的估计行数实际上与指定了OPTIMIZE FOR UNKNOWN相同.这是SQL Server 2005上的相同行为吗?我想我曾经记得听过一次没有更多信息,SQL Server优化引擎必须猜测参数的选​​择性(对于不等式谓词,通常为10%).我仍在寻找有关SQL 2005行为的确切信息.我不太确定信息是否存在......

更多信息2:要清楚,这个问题是要求比较UNKNOWN查询提示和我描述的参数屏蔽技术.

这是一个技术问题,而不是解决问题的问题.我考虑了很多其他选择,并坚持这一点.因此,这个问题的唯一目标是帮助我获得两种方法相同的信心.

Mic*_*art 4

好吧,我做了一些实验。我将把结果写在这里,但首先我想说,根据我所看到和知道的,我确信在 2005 年和 2008 年使用临时参数与使用 2008 年的 OPTIMIZE FOR UNKNOWN完全相同。至少在存储过程的上下文中是这样。

这就是我发现的。在上面的过程中,我使用的是 AdventureWorks 数据库。(但我使用类似的方法并为任何其他数据库获得类似的结果)我运行:

dbcc show_statistics ('Sales.SalesOrderDetail', IX_SalesOrderDetail_ProductID) 
Run Code Online (Sandbox Code Playgroud)

我在直方图中看到了包含 200 个步骤的统计数据。查看其直方图,我发现有 66 个不同的范围行(即 66 个不同的值未作为相等值包含在统计数据中)。添加 200 个相等行(来自每个步骤),我会得到 Sales.SalesOrderDetail 中 ProductId 的 266 个不同值的估计值。

表中有 121317 行,我可以估计每个 ProductId 平均有 456 行。当我查看测试过程的查询计划(以 xml 格式)时,我看到类似以下内容:

...
<QueryPlan DegreeOfParallelism="1"  >
  <RelOp NodeId="0" 
         PhysicalOp="Index Seek" 
         LogicalOp="Index Seek" 
         EstimateRows="456.079" 
         TableCardinality="121317"  />
    ...
  <ParameterList>
    <ColumnReference 
      Column="@newproductid" 
      ParameterRuntimeValue="(999)" />
  </ParameterList>
</QueryPlan>
...       
Run Code Online (Sandbox Code Playgroud)

因此,我知道 EstimateRows 值的来源(精确到小数点后三位),并且请注意查询计划中缺少 ParameterCompiledValue 属性。这正是使用 2008 年的 OPTIMIZE FOR UNKNOWN 时计划的样子