这看起来并不像参数嗅探。
的CompiledValue和RunTimeValue是所有参数不变,即使在bad.sqlplan
<ParameterList>
<ColumnReference Column="@p__linq__16" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__15" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__14" ParameterCompiledValue="(10776)" ParameterRuntimeValue="(10776)" />
<ColumnReference Column="@p__linq__13" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__12" ParameterCompiledValue="(0)" ParameterRuntimeValue="(0)" />
<ColumnReference Column="@p__linq__11" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__10" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__9" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" />
<ColumnReference Column="@p__linq__8" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" />
<ColumnReference Column="@p__linq__7" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" />
<ColumnReference Column="@p__linq__6" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__5" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__4" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" />
<ColumnReference Column="@p__linq__3" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__2" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" />
<ColumnReference Column="@p__linq__1" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__0" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" />
</ParameterList>
相反,它看起来好像你是从The Parameter Embedding Optimization受益。
查询文本在计划中被截断,但我可以看到您正在比较参数与文字的位置。也许这是一个catch all query
当您使用OPTION (RECOMPILE)
计划编制只具有用于传递的参数值工作。 SQL Server可以查看传递参数的值,并用TRUE
或FALSE
有效替换突出显示的表达式。
这可能允许它简化计划的整个分支,如果它们与传递的参数值无关。
这方面的一个简单的例子是
EXEC sys.sp_executesql
N'SELECT * FROM master..spt_values WHERE @Param <> 0 OPTION (RECOMPILE)',
N'@Param INT',
@Param = 0;
该计划被编译时@Param=0
和它仅需要对这个值所以@Param <> 0
可以在编译时被评价为false
和计划是正确的根本不访问表格。
没有OPTION (RECOMPILE)
你看这
EXEC sys.sp_executesql
N'SELECT * FROM master..spt_values WHERE @Param <> 0',
N'@Param INT',
@Param = 0;
即使嗅探到的参数值和运行参数值是相同的计划不能被优化到相同的程度因为它将被缓存,并且如果传递了不同的参数值,仍然需要工作。
这是一个参数嗅探问题的脚印之一。 – RBarryYoung
可能受益于[参数嵌入优化](http://sqlperformance.com/2013/08/t-sql-queries/parameter-sniffing-embedding-and-the-recompile-options)没有查询和计划谁知道? –
如果您将“好”计划与重新编译和“坏”计划进行比较,您应该弄清楚有什么不同。用于编译它的参数位于最左边的节点中。 –