SELECT TOP 10
q.query_hash
, count (distinct p.query_id ) AS number_of_distinct_query_ids
, min(qt.query_sql_text) AS sampled_query_text
FROM sys.query_store_query_text AS qt
JOIN sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan AS p
ON q.query_id = p.query_id
JOIN sys.query_store_runtime_stats AS rs
ON rs.plan_id = p.plan_id
JOIN sys.query_store_runtime_stats_interval AS rsi
ON rsi.runtime_stats_interval_id = rs.runtime_stats_interval_id
WHERE
rsi.start_time >= DATEADD(hour, -2, GETUTCDATE())
AND query_parameterization_type_desc IN ('User', 'None')
GROUP BY q.query_hash
ORDER BY count (distinct p.query_id) DESC;
影响查询计划更改的因素
重新编译查询执行计划可能会导致生成的查询计划与最初缓存的计划不同。 有多种原因可能导致自动重新编译现有的原始计划:
查询引用的架构发生更改
对查询引用的表进行数据更改
查询上下文选项已更改
编译的计划可能会出于各种原因从缓存中逐出,例如:
数据库范围的配置更改
清除缓存的显式请求
如果使用 RECOMPILE 提示,则不会缓存计划。
重新编译(或者在缓存逐出后重新编译)仍可能导致从生成与原始计划相同的查询执行计划。 如果计划与以前的或原始的计划不同,可能的解释如下:
更改了物理设计:例如,新建的索引可以更有效地解决查询要求。 如果查询优化器认为利用这些新索引比最初选择用于第一个版本的查询执行的数据结构更有利,则可以在新的编译中使用这些新索引。 对引用的对象进行任何物理更改可能会导致在编译时生成新的计划选项。
服务器资源差异:如果一个系统中的计划不同于另一个系统中的计划,则资源可用性(例如可用的处理器数)可能会影响生成的计划。 例如,如果一个系统的处理器数较多,则可能会选择并行计划。 有关 Azure SQL 数据库中的并行度的详细信息,请参阅在 Azure SQL 数据库中配置最大并行度 (MAXDOP)。
不同的统计信息:与引用的对象关联的统计信息发生了更改,或者与原始系统的统计信息有本质的差别。 如果统计信息发生更改并重新编译,则查询优化器将使用从更改时间开始的统计信息。 修改后的统计信息的数据分布和频率可能不同于原始编译中的情况。 这些更改用于创建基数估算。 (基数估算是预计要流经逻辑查询树的行数。)更改基数估算值可以引导我们选择不同的物理运算符和关联的操作顺序。 即使对统计信息进行少量的更改,也可能会导致查询执行计划发生变化。
更改了数据库兼容性级别或基数估算器版本:更改数据库兼容性级别可以启用新的策略和功能,从而可能导致生成不同的查询执行计划。 除了数据库兼容性级别以外,禁用或启用跟踪标志 4199 或更改数据库范围的配置 QUERY_OPTIMIZER_HOTFIXES 的状态也可能会影响编译时的查询执行计划选项。 跟踪标志 9481(强制旧式 CE)和 2312(强制默认 CE)也会影响计划。
资源限制问题
与欠佳查询计划和缺少索引无关的查询性能缓慢问题通常与资源不足或过度使用相关。 如果查询计划是最佳的,则原因可能是查询(和数据库)即将达到数据库或弹性池的资源限制。 例如,超过了服务级别的日志写入吞吐量限制。
使用 Azure 门户检测资源问题:若要确定问题是否与资源限制有关,请参阅 SQL 数据库资源监视。 对于单一数据库和弹性池,请参阅数据库顾问性能建议和查询性能见解。
使用数据库观察程序检测资源限制。
使用 DMV 检测资源问题:
sys.dm_db_resource_stats DMV 返回数据库的 CPU、I/O 和内存消耗量。 即使数据库中没有活动,也会每隔 15 秒返回一行数据。 历史数据将保留一小时。
sys.resource_stats DMV 返回 Azure SQL 数据库的 CPU 使用率和存储数据。 在 5 分钟间隔内收集并聚合数据。
存在许多单独的查询,它们共同消耗了很多的 CPU 资源
如果确定问题与资源不足有关,可以升级资源来增大数据库的容量,以满足 CPU 要求。 有关详细信息,请参阅在 Azure SQL 数据库中缩放单一数据库资源和在 Azure SQL 数据库中缩放弹性池资源。
应用程序流量和工作负荷量的增加可能会导致 CPU 使用率增大。 但是,要想正确诊断此问题,必须慎之又慎。 如果出现 CPU 使用率偏高的情况,请回答以下问题来确定 CPU 使用率增大是否由工作负荷量变化而引起:
来自应用程序的查询是否是导致高 CPU 问题的原因?
对于可以识别的 CPU 消耗量靠前的查询:
同一查询是否关联了多个执行计划? 如果是,为什么?
对于具有相同执行计划的查询,执行时间是否一致? 执行计数是否增加? 如果是,则性能问题可能是由工作负荷增加造成。
总而言之,如果查询执行计划没有以不同的方式执行,CPU 使用率却随执行计数的增加而增加,则可能出现了与工作负荷增加相关的性能问题。
要得出是工作负荷量变化导致 CPU 问题的结论并不容易。 请考虑以下因素:
资源使用率发生了变化:以 CPU 使用率长时间增加到 80% 的情况为例。 单凭 CPU 使用率并不能说明工作负荷量发生了变化。 即使应用程序执行的工作负荷完全相同,查询执行计划的回归和数据分布的变化也有可能导致资源使用率的增加。
出现了新查询:应用程序有可能在不同时间发出一组新的查询。
请求数量增加或减少:这种情况最能说明工作负荷量的变化。 查询数量并不一定与资源利用率增加相对应。 但是,在其他因素不变的前提下,该指标仍然是一个重要信号。
使用数据库观察程序检测工作负载增加和计划随时间推移的回归。
并行度:并行度过高会使其他查询得不到 CPU 和工作线程资源,从而使其他并发工作负载的性能降低。 有关 Azure SQL 数据库中的并行度的详细信息,请参阅在 Azure SQL 数据库中配置最大并行度 (MAXDOP)。
消除与执行问题相关的欠佳计划和等待相关问题后,性能问题通常与查询可能正在等待某个资源有关。 等待相关的问题的可能原因如下:
一个查询可能持有数据库中某些对象的锁,而其他查询正在尝试访问相同的对象。 可以使用 DMV 或数据库观察程序来识别阻塞的查询。 有关详细信息,请参阅了解并解决 Azure SQL 数据库阻塞问题。
IO 问题
查询可能正在等待将页面写入数据文件或日志文件。 在这种情况下,请检查 DMV 中的 INSTANCE_LOG_RATE_GOVERNOR、WRITE_LOG 或 PAGEIOLATCH_* 等待统计信息。 了解如何使用 DMV 识别 IO 性能问题。
Tempdb 问题
如果工作负荷使用大量的临时表,或者计划中存在大量的 tempdb 溢出,则可能表示查询遇到了 tempdb 吞吐量问题。 若要进一步调查,请查看确定 tempdb 问题。
内存相关的问题
如果工作负荷没有足够的内存,页生存期可能会下降,或者查询获得的内存量小于所需的量。 在某些情况下,查询优化器中的内置智能会解决内存相关的问题。 了解如何使用 DMV 识别内存授予问题。 有关示例查询的详细信息,请参阅排查 Azure SQL 数据库的内存不足错误。 如果遇到内存不足错误,请查看 sys.dm_os_out_of_memory_events。
用于显示最常见等待类别的方法
用于显示最常见等待类别的最常用方法如下:
使用数据库观察程序识别由于等待时间增加而出现性能降低的查询。
使用查询存储查找每个查询在不同时间段的等待统计信息。 在查询存储中,等待类型合并成等待类别。 可在 sys.query_store_wait_stats 中找到等待类别到等待类型的映射。
使用 sys.dm_db_wait_stats 返回有关查询操作期间执行的线程遇到的所有等待的信息。 可以使用此聚合视图来诊断 Azure SQL 数据库以及特定查询和批的性能问题。 查询可能正在等待资源,发生了队列等待或外部等待。
使用 sys.dm_os_waiting_tasks 返回有关正在等待某个资源的任务队列的信息。
在 CPU 使用率偏高时,如果存在以下情况,查询存储和等待统计信息可能不会反映 CPU 使用率:
CPU 消耗量较高的查询仍在执行。
发生故障转移时,正在运行 CPU 消耗量较高的查询。
跟踪查询存储和等待统计信息的 DMV 仅显示成功完成的查询和超时查询的结果。 它们不显示当前正在执行的语句的数据(直到其完成)。 使用动态管理视图 sys.dm_exec_requests 跟踪当前正在执行的查询以及相关的工作线程时间。
其他工具:
TigerToolbox 等待和闩锁
TigerToolbox usp_whatsup
在 Azure SQL 数据库中配置最大并行度 (MAXDOP)
了解并解决 Azure SQL 数据库阻塞问题
诊断和排查 Azure SQL 数据库上的高 CPU 问题
SQL 数据库监视和优化概述
使用动态管理视图监视 Microsoft Azure SQL 数据库的性能
使用缺失索引建议优化非聚集索引
Azure SQL 数据库中的资源管理
使用 vCore 购买模型的单一数据库的资源限制
使用 vCore 购买模型的弹性池的资源限制
使用 DTU 购买模型的单一数据库的资源限制
使用 DTU 购买模型的弹性池的资源限制