使用选项运行SQL查询(重新编译)总是更快

时间:2014-09-22 09:42:55

标签: sql sql-server indexing sql-execution-plan parameter-sniffing

这可能是this question的副本,虽然我认为我的例子有点深入,我希望得到更明确的答案。 我试图理解为什么使用option(recompile)运行简单查询效果更好。

DECLARE @p9 nvarchar(4000)
SET @p9=N'Alex%'

SELECT ContactId as CandidateId
FROM Candidate
            WHERE
                (
                    @p9 IS NULL
                    OR
                    Forename LIKE @p9
                    OR 
                    PreferredName LIKE @p9
                    OR
                    Surname LIKE @p9
                )

在没有option(recompile)的情况下运行(无论我运行多少次)

(1166 row(s) affected)
Table 'Candidate'. Scan count 5, logical reads 9762, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Execution plan with no recompile option specified

完全相同的查询,但最后添加了option(recompile)

(1166 row(s) affected)
Table 'Candidate'. Scan count 3, logical reads 18, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Execution plan with no recompile option specified

如果我不在查询中使用变量,而是使用常量,那么一切都很好。我认为它与参数嗅探有关,但问题是为什么? 将option(recompile)留给生产代码会有什么缺点?

我还在应用程序中运行了一些运行查询的诊断测试,而option(recompile)似乎总是更快的结果。

更新:正在运行exec sp_updatestats无效,option(recompile)选择仍然可以更好地执行。

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

Option(recompile)根据当前统计信息生成新计划,但需要编制新计划。如果您的统计数据是最新的,那么99次中的100次,您将获得最佳计划(而不是缓存的查询计划,这可能不适合您传入的特定参数集,与计划缓存时相比)。这被称为参数嗅探)

  

“还有什么是留下选项(重新编译)的缺点   生产代码?“

对于报告查询来说这很好,但对于每秒运行多次的查询来说是个坏主意,因为每次重新编译计划的成本可能超过实际执行查询的成本!

另外,请注意使用Option(recompile)的缺点是该程序不会出现在相关的DMV中。