sys.dm_exec_query_stats与重新编译的交互

我们使用sys.dm_exec_query_stats来追踪缓慢的查询和查询,这些是IO违规者。

这很好,我们得到了很多非常有见地的数据。 很明显,这并不像运行一个profiler跟踪那样准确,因为你不知道SQL Server何时决定执行一个执行计划。

我们有很多查询错误的执行计划被caching。 例如下面的查询:

selectTOP 30
        援助
 FROMposta
         JOINpostq ON q.Id = a.ParentId
         JOIN PostTags pt ON q.Id = pt.PostId
 WHERE a.PostTypeId = 2
         AND a.DeletionDate IS NULL
         AND a.CommunityOwnedDate IS NULL
         AND a.CreationDate> @date
        和LEN(a.Body)> 300
         AND pt.Tag = @tag
         AND a.Sore> 0
 ORDER BY aCore DESC

问题是理想的计划真的取决于所选的date(理想计划的截图):

理想的计划

但是,如果错误的计划被caching,当date范围很大时,它会完全窒息:(注意大胖子)

错误的计划

为了克服这个问题,我们build议使用OPTION (OPTIMIZE FOR UNKNOWN)OPTION (RECOMPILE)

OPTIMIZE FOR UNKNOWN导致一个稍微好一点的计划,这远非最佳。 在sys.dm_exec_query_stats中跟踪执行。

RECOMPILE导致select最好的计划,但是不会执行任何计算,并会在sys.dm_exec_query_stats中跟踪统计信息。

有没有另外一个DMV我们可以用来跟踪OPTION (RECOMPILE)查询的统计信息? 这是行为的devise? 有没有另外一种方法可以在sys.dm_exec_query_stats跟踪统计信息的同时进行重新编译?

注意:框架将始终使用sp_executesql执行参数化查询

也许你应该使用计划指南而不是选项RECOMPILE。 您已经有了一个很好的计划,只需将其添加为查询的计划指南,然后优化程序就会每次生成此计划。 请参阅使用计划指南优化已部署应用程序中的查询,并使用计划强制指定查询计划 。

在你的情况是非常微不足道的,只需要调用sp_create_plan_guide_from_handle良好的查询计划句柄:

您可以使用此存储过程来确保查询优化器始终为指定的查询使用特定的查询计划。