3

这可能是这个问题的重复,尽管我认为我的例子更深入一些,我希望得到更明确的答案。我试图理解为什么运行简单查询的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.

未指定重新编译选项的执行计划

相同的查询,但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.

未指定重新编译选项的执行计划

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

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

更新:运行exec sp_updatestats没有效果,并且选择option(recompile)仍然执行得更好。

感谢您的时间。

4

1 回答 1

3

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

“另外,为生产代码保留选项(重新编译)会有什么缺点?”

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

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

于 2014-09-22T09:45:30.317 回答