sql - 选项(重新编译)总是更快;为什么?

标签 sql sql-server sql-server-2008 compilation query-hints

我遇到了一种奇怪的情况,将OPTION (RECOMPILE)附加到我的查询中会导致它在半秒内运行,而忽略它会导致查询花费五分钟多一点。

当从查询分析器或我的 C# 程序通过 SqlCommand.ExecuteReader() 执行查询时就会出现这种情况。调用(或不调用)DBCC FREEPROCCACHEDBCC dropcleanbuffers 没有区别;使用 OPTION (RECOMPILE) 时,查询结果总是立即返回,如果不使用它,查询结果会超过五分钟。始终使用相同的参数调用查询[为了进行此测试]。

我使用的是 SQL Server 2008。

我对编写 SQL 相当满意,但之前从未在查询中使用过 OPTION 命令,并且在扫描此论坛上的帖子之前也不熟悉计划缓存的整个概念。我从帖子中了解到,OPTION (RECOMPILE) 是一项昂贵的操作。它显然为查询创建了一个新的查找策略。那么为什么省略OPTION (RECOMPILE)的后续查询如此慢呢?后续查询是否应该使用在包含重新编译提示的先前调用中计算出的查找策略?

每次调用都需要重新编译提示的查询是非常不寻常的吗?

很抱歉问了这个入门级问题,但我对此一无所知。

更新:我被要求发布查询...

select acctNo,min(date) earliestDate 
from( 
    select acctNo,tradeDate as date 
    from datafeed_trans 
    where feedid=@feedID and feedDate=@feedDate 

    union 

    select acctNo,feedDate as date 
    from datafeed_money 
    where feedid=@feedID and feedDate=@feedDate 

    union 

    select acctNo,feedDate as date 
    from datafeed_jnl 
    where feedid=@feedID and feedDate=@feedDate 
)t1 
group by t1.acctNo
OPTION(RECOMPILE)

从查询分析器运行测试时,我在前面添加以下几行:

declare @feedID int
select @feedID=20

declare @feedDate datetime
select @feedDate='1/2/2009'

从我的 C# 程序调用它时,参数通过 SqlCommand.Parameters 属性传入。

出于本次讨论的目的,您可以假设参数永远不会改变,因此我们可以排除次优参数嗅觉的原因。

最佳答案

有时使用OPTION(RECOMPILE)是有意义的。根据我的经验,这是唯一可行的选择是当您使用动态 SQL 时。在您探讨这对您的情况是否有意义之前,我建议您重建您的统计数据。这可以通过运行以下命令来完成:

EXEC sp_updatestats

然后重新创建您的执行计划。这将确保在创建执行计划时它将使用最新信息。

添加OPTION(RECOMPILE)会在每次执行查询时重建执行计划。我从未听说过这种描述为创建新的查找策略,但也许我们只是对同一事物使用不同的术语。

当创建存储过程时(我怀疑您从 .NET 调用 ad-hoc sql,但是 if you are using a parameterized query then this ends up being a stored proc call )SQL Server 尝试根据数据库中的数据和参数确定此查询的最有效执行计划传入( parameter sniffing ),然后缓存该计划。这意味着,如果您在数据库中有 10 条记录时创建查询,然后在有 100,000,000 条记录时执行该查询,则缓存的执行计划可能不再是最有效的。

总之 - 我不认为 OPTION(RECOMPILE) 在这里有任何好处。我怀疑您只需要更新您的统计数据和执行计划。根据您的具体情况,重建统计数据可能是 DBA 工作的重要组成部分。如果您在更新统计数据后仍然遇到问题,我建议您发布两个执行计划。

回答你的问题 - 是的,我想说,对于你的最佳选择来说,每次执行查询时重新编译执行计划是非常不寻常的。

关于sql - 选项(重新编译)总是更快;为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20864934/

相关文章:

SQL 查询 - 计数 - 最大值

sql - 以最少的中断截断新内容并将其插入表中

SQL 查询 - 对多个表进行分组

sql-server - 如何在 Visual Studio 2012 中调试 SQL Server T-SQL

java - SQL Server 2016 : Enable TLS 1. 2 用于 SQL Server 连接

sql-server - 为什么合并复制在设置表的 LOCK_ESCALATION 时会失败?

sql - 我们可以向 SQL Server 数据库/表添加注释或自述文件吗?

SQL 查询 JOIN 或 IN 运算符?

java - 如何在HyperSQL中支持SqlServer的 ".."?

sql-server - 使用脚本进行事务复制