为什么查询存储缺少详细信息?

Jam*_*ins 7 sql-server query-store

这解释起来有点复杂,但很容易重现。

精简版:

对于大约 10%-30% 的查询(按计数),大量的查询存储数据不可用。我查看了 SQL 2016 和 SQL 2017,其中查询存储已经运行了数周以上,数据库上有活动。

下面的查询将返回两组数据,顶部集没有 值query_store_query.last_execution_time,而底部集在字段中有数据。“没有”也缺少大多数运行时统计数据。

EXEC sp_query_store_flush_db;  --Same results without this, but just to rule it out in the examples. 
go
Select * from sys.query_store_query
where query_store_query.last_execution_time is null -- there are bunch of these, also missing other data, why? 

Select * from sys.query_store_query
where query_store_query.last_execution_time is not null 
Run Code Online (Sandbox Code Playgroud)

问题解决:

  1. 我最初使用导出的查询存储数据发现了这一点我的数据在 Excel 工作表中,我进行了排序和比较,但没有发现任何将“拥有”与“没有”分开的共同因素

  2. 为了排除数据导出问题,我使用上面的代码直接从系统数据视图中获取数据。结果与导出数据中的结果相似。

  3. 为了排除系统数据视图,我使用“跟踪查询”从根数据报告。(查询存储 > 跟踪查询 > 配置)

    3.A. 对于“拥有”,查询计划等会显示出来,正如您所期望的

    3.B. 对于“没有”,没有查询计划和指标

  4. 我发现的唯一范围限制因素是,在非常活跃的数据库上,“没有”仅限于最后几个小时。但是在慢速数据库上,“没有”可能有可以追溯到几周前的 initial_compile_start_time。(我怀疑“没有”正在被清除,然后在下次运行“以前从未见过,新”查询时重新创建

  5. “没有”可以有任何范围的编译计数、计划数量等。

“没有”有什么共同点?为什么他们丢失数据而其他人没有?

为什么这很重要:如果正如我目前怀疑的那样,没有在“没有”上正确捕获运行时数据,则查询存储报告中可能不会报告某些/所有资源最密集的查询。

更新:查询存储捕获​​模式All并没有消除这个问题。

使用Erin Stellato建议设置,我将 Query Store Capture Mode 设置为Auto,正如评论和回答中指出的那样,这可能是原因。但是经过测试(清除了我的一个数据库上的 QS 并将其设置为 ALL),在数据库运行了一段时间后,我仍然看到一些“没有”

Jos*_*ell 4

我在我的 SQL Server 2016 实例上也看到了这一点(与您的设置相同:15 分钟数据刷新和 1 小时统计信息收集)。我注意到缺少信息的计划与 AG 故障转移和维护相关的重新启动相关(我通过查看 SQL Server 错误日志发现了这一点)。

如果您像我一样遵循与“关键任务服务器”相关的最佳实践,您可能已经采取了以下步骤:

在关键任务服务器上使用跟踪标志

全局跟踪标志 7745 和 7752 可用于提高使用查询存储的数据库的可用性。有关详细信息,请参阅跟踪标志。

  • 跟踪标志 7745 将阻止在 SQL Server 关闭之前查询存储将数据写入磁盘的默认行为。这意味着已收集但尚未持久化到磁盘的查询存储数据将会丢失。

  • 跟踪标志 7752 启用查询存储的异步加载。这允许数据库在线并在查询存储完全恢复之前执行查询。默认行为是同步加载查询存储。默认行为会阻止查询在恢复查询存储之前执行,同时也会阻止数据收集中遗漏任何查询。

这解释了我的设置中所有缺少的运行时统计信息。虽然本文中没有明确指出,但查询和计划似乎可能会在没有聚合运行时统计信息的情况下进入查询存储。这可能会根据您的“数据刷新间隔”和“统计信息收集间隔”而有所不同。