Jor*_*val 2 performance sql-server execution-plan
这是在 SQL 2005 SP2 上,但我怀疑这通常适用于所有查询提示。
我有一个临时的 sql 语句,它仅仅因为 OPTION(重新编译)而获得不同的查询计划。批处理语句永远不会(实际上)被重用,因为它使用非参数化动态 sql 生成,其中语句随日期/其他参数而变化。我已经通过检查缓存的 plan_handle 确认了这种情况,在批量更改时总是使用不同的 ID。
当我执行 dbcc freeproccache 时,我希望我为语句获得的查询计划与添加了“选项(重新编译)”查询提示的查询计划完全相同。但它不是,它实际上完全不同(要快得多)。
有谁知道为什么添加查询提示会导致引擎选择不同的查询计划?
声明是这样的
dbcc freeproccache
go
sp_executesql '
declare @begindate datetime
declare @enddate datetime
select @begindate='1/1/2011'
select @enddate='2/1/2011'
select count(*) from tableA where tableA.datecolumn between @begindate and @enddate
and exists(
select A
union all select B
union all select C
)'
Run Code Online (Sandbox Code Playgroud)
我所要做的就是更改语句以使用重新编译查询提示,然后我会得到不同的(更好的)查询计划。
dbcc freeproccache
go
sp_executesql '
declare @begindate datetime
declare @enddate datetime
select @begindate='1/1/2011'
select @enddate='2/1/2011'
select count(*) from tableA where tableA.datecolumn between @begindate and @enddate
and exists( select A
union all select B
union all select C
) OPTION (RECOMPILE)'
Run Code Online (Sandbox Code Playgroud)
当代码传入日期值时,我无法使用计划指南来覆盖默认行为,看起来需要更改代码。但我希望我知道在哪里查看为什么重新编译会强制使用不同的计划。
您发布的查询包含变量。
SQL Server 不进行变量嗅探,因此OPTION (RECOMPILE)它不会像对OPTIMIZE FOR UNKNOWN.
我并没有真正关注你的问题。有一次,您似乎在说没有提示的版本“要快得多”,然后您说带提示的版本“要好得多”。那么是哪一个呢?
然而,两者都是可以解释的。如果您发现带有提示的版本比这更好,因为 SQL Server 可以使用统计信息来估计日期谓词将匹配的行数,并为该情况选择合适的计划。
如果没有提示的版本更好,则统计信息本身可能需要更新。也许当它们上次更新时,满足该谓词的行很少或没有,因此 SQL Server 大大低估了将返回的行数。有关此潜在问题的更多信息,请参阅统计信息、行估计和升序日期列。