我从一开始说,我的问题/问题类似于此之前的一个,但因为我不知道的原因或起始信息是一样的,我决定后,我的问题有一些更多的细节。
当前问题:
- 在一个奇怪的时刻(工作日临近结束),生产实例开始出现异常行为:
- 实例的CPU较高(从约30%的基准开始,它增加了约一倍,并且仍在增长)
- 每秒增加的事务数(尽管应用程序负载未发生任何变化)
- 空闲会话数增加
- 从未显示此行为的会话之间发生奇怪的阻止事件(即使读取未提交的会话也导致了阻止)
- 等待间隔的最长时间是第一页上的非页面锁,第二名是锁
初步调查:
- 使用sp_whoIsActive,我们看到了由监视工具执行的查询决定运行速度非常慢,并占用大量CPU,这在以前是没有发生的。
- 隔离级别未提交;
- 我们查看了看到古怪数字的计划:StatementEstRows =“ 3.86846e + 010”,其中约150 TB的估计数据已返回
- 我们怀疑原因是监视工具的查询监视功能引起了,因此我们禁用了该功能(我们还与提供程序一起打开了一张票证,以检查他们是否知道任何问题)
- 从第一个事件开始,它又发生了几次,每次我们终止会话时,一切都恢复正常;
- 我们意识到查询极为相似的一个查询在BOL使用MS用于查询存储监测-查询,最近在性能倒退(在时间上比较不同点)
- 我们手动运行相同的查询并看到相同的行为(使用的CPU不断增加,闩锁等待时间增加,意外锁定等。)
有罪查询:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
设置和信息:
- Windows Server 2012R2群集上的SQL Server 2016 SP1 CU4企业
- 查询存储已启用并配置为默认值(未更改设置)
- 从SQL 2005实例导入的数据库(仍处于兼容级别100)
实证观察:
- 由于统计数据极其古怪,我们将所有在错误的估算计划中使用的* plan_persist **对象(尚无实际计划,导致查询从未完成)并检查了统计信息,该计划中使用的某些索引没有任何统计信息(DBCC SHOWSTATISTICS没有返回任何内容,请从sys.stats中选择,对某些索引显示NULL stats_date()函数
快速而肮脏的解决方案:
- 在与查询存储或
- 强制使用新的CE(跟踪标记)运行查询-这还将创建/更新必要的统计信息,或者
- 将数据库的兼容性级别更改为130(因此默认情况下将使用新的CE)
因此,我的真正问题是:
为什么查询存储上的查询会导致整个实例的性能问题?我们是否在Query Store的bug领域?
PS:我将很快上传一些文件(打印屏幕,IO状态和计划)。
在Dropbox上添加的文件。
计划1-生产中最初的古怪估计计划
计划2-测试环境中的实际计划,旧的CE(相同的行为,相同的统计数据)
计划3-测试环境中的实际计划,新的CE