我遇到了一种奇怪的情况,将OPTION (RECOMPILE)
附加到我的查询中会导致它在半秒内运行,而忽略它会导致查询花费五分钟多一点。
当从查询分析器或我的 C# 程序通过 SqlCommand.ExecuteReader()
执行查询时就会出现这种情况。调用(或不调用)DBCC FREEPROCCACHE
或 DBCC 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/