我们用来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
使用良好的查询计划处理:
您可以使用此存储过程来确保查询优化器始终对指定查询使用特定的查询计划。