我遇到了一个奇怪的情况,附加OPTION (RECOMPILE)到我的查询会导致它在半秒内运行,而省略它会导致查询花费超过五分钟。
OPTION (RECOMPILE)
当从查询分析器或我的 C# 程序通过SqlCommand.ExecuteReader(). 打电话(或不打电话)DBCC FREEPROCCACHE或DBCC dropcleanbuffers没有区别;查询结果总是会在OPTION (RECOMPILE)超过五分钟后立即返回。始终使用相同的参数调用查询 [为了这个测试]。
SqlCommand.ExecuteReader()
DBCC FREEPROCCACHE
DBCC dropcleanbuffers
我正在使用 SQL Server 2008。
我对编写 SQL 相当满意,但以前从未OPTION在查询中使用过命令,并且在浏览此论坛上的帖子之前对计划缓存的整个概念并不熟悉。我从帖子中了解到这OPTION (RECOMPILE)是一项昂贵的操作。它显然为查询创建了一个新的查找策略。那么,为什么省略 的后续查询OPTION (RECOMPILE)如此缓慢呢?后续查询不应该使用在先前调用中计算的包含重新编译提示的查找策略吗?
OPTION
每次调用都需要重新编译提示的查询是不是很不寻常?
对不起,入门级的问题,但我真的不能做出正面或反面。
更新:我被要求发布查询…
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属性传入的。
SqlCommand.Parameters
出于本讨论的目的,您可以假设参数永远不会改变,因此我们可以排除次优参数异味的原因。
有时使用OPTION(RECOMPILE)是有意义的。根据我的经验,唯一可行的选择是在您使用动态 SQL 时。在您探索这对您的情况是否有意义之前,我建议您重建您的统计数据。这可以通过运行以下命令来完成:
OPTION(RECOMPILE)
EXEC sp_updatestats
然后重新创建你的执行计划。这将确保在创建执行计划时将使用最新信息。
每次执行查询时,添加OPTION(RECOMPILE)都会重建执行计划。我从未听说过这样的描述,creates a new lookup strategy但也许我们只是对同一件事使用不同的术语。
creates a new lookup strategy
创建存储过程时(我怀疑您正在从 .NET 调用 ad-hoc sql,但如果您使用的是参数化查询,那么这最终会成为存储过程调用)SQL Server 尝试确定此查询的最有效执行计划根据你数据库中的数据和传入的参数),然后缓存这个计划。这意味着,如果您在数据库中有 10 条记录的情况下创建查询,然后在有 100,000,000 条记录时执行它,则缓存的执行计划可能不再是最有效的。
总而言之-我认为OPTION(RECOMPILE)这里没有任何好处。我怀疑你只需要更新你的统计数据和你的执行计划。根据您的情况,重建统计信息可能是 DBA 工作的重要组成部分。如果您在更新统计信息后仍然遇到问题,我建议您同时发布两个执行计划。
并回答您的问题 - 是的,我会说每次执行查询时重新编译执行计划的最佳选择是非常不寻常的。