sql-server – sys.dm_exec_query_stats与重新编译的交互

我们使用sys.dm_exec_query_stats来跟踪IO查询者的慢查询查询.

这很有效,我们获得了许多非常有见地的统计数据.很明显,这不像运行探查器跟踪那样准确,因为您不知道sql Server何时决定放弃执行计划.

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

SELECT TOP 30
        a.Id
FROM    Posts a
        JOIN Posts q 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
        AND LEN(a.Body) > 300
        AND pt.Tag = @tag
        AND a.score > 0
ORDER BY a.score DESC

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

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

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

对未知的优化导致稍微更好的计划,这远非最佳.在sys.dm_exec_query_stats中跟踪执行.

RECOMPILE会导致选择最佳计划,但不会在sys.dm_exec_query_stats中跟踪执行计数和统计信息.

我们可以使用另一个DMV来跟踪OPTION(RECOMPILE)查询统计数据吗?
这种行为是按设计的吗?
还有另一种方法可以在sys.dm_exec_query_stats中跟踪统计数据的同时进行重新编译吗?

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

解决方法

也许您应该使用计划指南而不是选项RECOMPILE.您已经有了一个好的计划,所以只需将其添加查询的计划指南,然后优化器就会生成此计划.见 Optimizing Queries in Deployed Applications by Using Plan GuidesSpecifying Query Plans with Plan Forcing.

在你的情况下是非常简单的,只需使用良好的查询计划句柄调用sp_create_plan_guide_from_handle

You can use this stored procedure to ensure the query optimizer always uses a specific query plan for a specified query.

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...