sys.dm_exec_query_stats 与重新编译的交互

sys.dm_exec_query_stats 与重新编译的交互

我们用来sys.dm_exec_query_stats追踪慢速查询和 IO 违规查询。

这很有效,我们得到了很多非常有见地的统计数据。很明显,这不如运行分析器跟踪那么准确,因为你不知道 SQL Server 何时会决定放弃执行计划。

我们有相当多的查询缓存了错误的执行计划。例如以下查询:

选择前 30 名
        援助
来自帖子
        加入帖子 q ON q.Id = a.ParentId
        加入帖子标签 pt ON q.Id = pt.PostId
其中 a.PostTypeId = 2
        并且 a.DeletionDate 为空
        并且 a.CommunityOwnedDate 为空
        并且 a.CreationDate > @date
        并且 LEN(a.Body) > 300
        并且 pt.Tag = @tag
        并且 a.Score > 0
按分数降序排列

问题是,理想的计划确实取决于所选的日期(理想计划的屏幕截图):

理想计划

然而,如果错误的计划被缓存,当日期范围很大时它会完全阻塞:(注意大粗线)

错误的计划

OPTION (OPTIMIZE FOR UNKNOWN)为了解决这个问题,我们建议使用OPTION (RECOMPILE)

OPTIMIZE FOR UNKNOWN结果是略好一些的计划,但远非最优。执行情况在 中进行跟踪sys.dm_exec_query_stats

RECOMPILE结果是选择了最佳方案,但是执行无效并跟踪统计数据sys.dm_exec_query_stats

是否有其他 DMV 可用于跟踪查询统计信息OPTION (RECOMPILE)?此行为是设计使然吗?是否有其他方法可以重新编译,同时保持跟踪统计信息sys.dm_exec_query_stats

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

答案1

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

在你的情况下真的很简单,只需调用sp_create_plan_guide_from_handle使用良好的查询计划处理:

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

相关内容