sys.dm_exec_query_stats 与重新编译的交互

Sam*_*ron 7 performance sql-server sql-server-2008

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

这很好用,我们得到了很多非常有见地的统计数据。很明显,这不如运行探查器跟踪准确,因为您不知道 SQL Server 何时决定放弃执行计划。

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

选择前 30 名
        援助
FROM 帖子 a
        加入帖子 q ON q.Id = a.ParentId
        加入 PostTags pt ON q.Id = pt.PostId
哪里 a.PostTypeId = 2
        并且 a.DeletionDate 为 NULL
        并且 a.CommunityOwnedDate 为 NULL
        AND a.CreationDate > @date
        AND LEN(a.Body) > 300
        AND pt.Tag = @tag
        AND a.Score > 0
按 a.Score DESC 排序

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

理想计划

但是,如果缓存了错误的计划,则当日期范围很大时它会完全窒息:(注意大粗线)

错误的计划

为了克服这个问题,我们建议使用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 执行参数化查询

Rem*_*anu 1

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

在您的情况下,这确实很简单,只需sp_create_plan_guide_from_handle使用良好的查询计划句柄进行调用即可:

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