适用于: SQL Server 2022 (16.x)及更高版本 Azure SQL 数据库
Azure SQL 托管实例
针对可读辅助副本的查询存储可为在辅助副本上运行的工作负载启用查询存储洞察功能。 启用后,次要副本会将查询执行信息(如运行时和等待统计信息)流式传输到主副本,其中数据保存在查询存储中,并在所有副本中可见。
注释
适用于可读次要副本的查询存储目前在所有 SQL 数据库引擎 平台中处于预览状态。
可用性
从 SQL Server 2025 (17.x) 开始,Azure SQL 数据库和使用 Always-up-to-date 更新策略 的 Azure SQL 托管实例也支持可读次要副本的 查询存储。 对于 SQL Server 2022 (16.x),要使用可读二级副本的查询存储功能,需要启用跟踪标志 12606。
下表汇总了可读辅助副本的可用性以及 Query Store 的启用状态。
| 平台 | 可用 | 默认启用 |
|---|---|---|
| Azure SQL 数据库 | 是1 | 是(始终启用) |
| Microsoft Fabric中的 SQL 数据库 | 是的 | 是(始终启用) |
| Azure SQL 托管实例AUTD | 是的 | 是(始终启用) |
| Azure SQL 托管实例2025 | 否 | 否 |
| Azure SQL 托管实例2022 | 否 | 否 |
| SQL Server 2025 (17.x) | 是的 | 否(可按数据库启用) |
| SQL Server 2022 (16.x) | 否2 | 否 |
1 目前,Azure SQL 数据库 的 Hyperscale 服务层不支持可读辅助节点的查询存储。
2 对于 SQL Server 2022 (16.x),可读辅助节点的查询存储仍处于 有限 预览阶段,因此 不 支持在生产环境中使用,并且默认处于禁用状态。 若仅要在 SQL Server 2022 (16.x) 中启用可读辅助节点的查询存储,则需在主节点和所有可读辅助副本上启用跟踪标志 12606。 跟踪标志 12606 不适用于基于 SQL Server 2022 (16.x) 的生产部署。 有关详细信息,请参阅 SQL Server 2022 发行说明。
支持的高可用性场景
在对 SQL Server 2025 (17.x) 实例的可读次要副本使用 查询存储 之前,必须配置 Always On 可用性组。
对于Azure SQL 数据库,可读次要副本的查询存储支持以下服务层级:
对于 采用“始终保持最新”策略的 Azure SQL 托管实例,可读辅助副本的查询存储支持以下服务层:
- 带 故障转移组 的通用型(无内置高可用性副本;需要配置故障转移组以支持辅助副本)
- 业务关键型(包含内置的高可用性副本)
为可读次要副本启用查询存储
如果尚未在主副本上启用 查询存储 并以 READ_WRITE 模式运行,那么在继续操作之前必须先启用它。 对主副本上的每个所需数据库执行以下脚本:
ALTER DATABASE [Database_Name]
SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE);
若要在所有可读次要副本上启用查询存储,请连接到主副本,并为要登记使用该功能的每个数据库执行以下脚本。
ALTER DATABASE [Database_Name]
FOR SECONDARY
SET QUERY_STORE = ON
(OPERATION_MODE = READ_WRITE);
注释
在版本 21 SQL Server Management Studio(SSMS)之前,FOR SECONDARY 语法有效,但 IntelliSense 无法识别。 对于 SQL Server 2022,SSMS IntelliSense 无法将 FOR SECONDARY 语法识别为有效,但它有效。
为次要副本启用自动执行计划修正
应用到:SQL Server 2022(16.x)及更高版本,Azure SQL 数据库。
为次要副本启用 查询存储 后,可以选择启用自动调优,从而允许自动计划校正功能在次要副本上强制执行计划。 这使查询优化器能够自动识别和修复辅助副本上执行计划回归导致的查询性能问题。
若要为次要副本启用自动计划更正,请连接到主副本并为每个所需数据库执行以下脚本:
ALTER DATABASE [Database_Name]
FOR SECONDARY
SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = ON);
为次要副本禁用查询存储
若要在所有辅助副本上禁用 查询存储 对于辅助副本的功能,请连接到 master 副本上的 primary 数据库,并为每个所需数据库执行以下脚本:
ALTER DATABASE [Database_Name]
FOR SECONDARY
SET QUERY_STORE = ON
(OPERATION_MODE = READ_ONLY);
验证次要副本上是否已启用查询存储
可以通过连接到辅助副本上的数据库并执行以下 T-SQL 语句,验证是否在 secondary 副本上启用查询存储:
SELECT desired_state_desc,
actual_state_desc,
readonly_reason
FROM sys.database_query_store_options;
查询 sys.database_query_store_options 目录视图的结果应表明,查询存储的实际状态为 READ_CAPTURE_SECONDARY,其 readonly_reason 值为 8。
desired_state_desc |
actual_state_desc |
readonly_reason |
|---|---|---|
READ_CAPTURE_SECONDARY |
READ_CAPTURE_SECONDARY |
8 |
注解
术语
副本集定义为数据库的读/写副本(主副本)和一个或多个只读副本(辅助副本)被视为逻辑单元。 在此上下文中,角色 指特定副本的角色。 当副本担任主角色时,它是读写副本,既可执行数据修改操作,也可执行读取操作。 当副本被配置为仅执行只读操作时,它即处于次要角色(次要、地理次要、地理高可用性次要)。 角色可通过计划内或计划外故障转移事件发生变化,此时主副本可能变为次要副本,反之亦然。
当前支持的角色包括:
- 主要
- 次要
- 地理次要
- 地理高可用性次要
- 命名副本
工作原理
关于查询存储的数据可以按角色作为工作负载进行分析。 对于可读次要副本,查询存储使你能够监视可能针对次要副本执行的任何唯一只读工作负荷的性能。 数据在角色级别聚合。 例如,SQL Server 分布式可用性组配置可能包括:
一个主要复制品,属于可用性组 1 (AG1) 的一部分
两个本地次要副本,也是 AG1 的一部分
位于另一个位置且属于独立可用性组(AG2)的一个远程主副本。 在 SQL Server 术语中,它通常也被称为全局转发器,但“可读次要副本的查询存储”功能会将其识别并称为
Geo secondary副本,前提是它是一个地理分布式次要副本。
如果将 AG1 和 AG2 配置为允许只读连接,则当只读工作负荷针对 AG1 的任一辅助副本执行时,查询存储执行统计信息将发送到 AG1 的主副本,并聚合并保留为从 secondary 角色生成的数据,然后再将数据发送回 AG2 中的所有次要副本,包括全局转发器。 当针对 AG2 的主副本(即全局转发器)执行独立工作负载时,其数据会被发回至 AG1 的主副本,并作为由 Geo secondary 角色生成的数据进行持久化。
从可观察性的角度来看,扩展了sys.query_store_runtime_stats 系统目录视图,以帮助识别执行统计信息的源角色。 此视图与 sys.query_store_replicas 系统目录视图之间存在关系,该视图可以提供更友好的角色名称。 在 SQL Server 中,replica_name 列为 NULL。 但是,如果存在命名副本且该副本正用于只读工作负载,则超大规模服务层中的 replica_name 列也会被填充。
T-SQL 查询的一个示例,该查询可用于提供过去 8 小时内前 50 个查询的总体分析,消耗所有副本的 CPU 资源将是:
-- Top 50 queries by CPU across all replicas in the last 8 hours
DECLARE @hours AS INT = 8;
SELECT TOP 50 qsq.query_id,
qsp.plan_id,
CASE qrs.replica_group_id WHEN 1 THEN 'PRIMARY' WHEN 2 THEN 'SECONDARY' WHEN 3 THEN 'GEO SECONDARY' WHEN 4 THEN 'GEO HA SECONDARY' ELSE CONCAT('NAMED REPLICA_', qrs.replica_group_id) END AS replica_type,
qsq.query_hash,
qsp.query_plan_hash,
SUM(qrs.count_executions) AS sum_executions,
SUM(qrs.count_executions * qrs.avg_logical_io_reads) AS total_logical_reads,
SUM(qrs.count_executions * qrs.avg_cpu_time / 1000.0) AS total_cpu_ms,
AVG(qrs.avg_logical_io_reads) AS avg_logical_io_reads,
AVG(qrs.avg_cpu_time / 1000.0) AS avg_cpu_ms,
ROUND(TRY_CAST (SUM(qrs.avg_duration * qrs.count_executions) AS FLOAT) / NULLIF (SUM(qrs.count_executions), 0) * 0.001, 2) AS avg_duration_ms,
COUNT(DISTINCT qsp.plan_id) AS number_of_distinct_plans,
qsqt.query_sql_text
FROM sys.query_store_runtime_stats_interval AS qsrsi
INNER JOIN sys.query_store_runtime_stats AS qrs
ON qrs.runtime_stats_interval_id = qsrsi.runtime_stats_interval_id
INNER JOIN sys.query_store_plan AS qsp
ON qsp.plan_id = qrs.plan_id
INNER JOIN sys.query_store_query AS qsq
ON qsq.query_id = qsp.query_id
INNER JOIN sys.query_store_query_text AS qsqt
ON qsq.query_text_id = qsqt.query_text_id
WHERE qsrsi.start_time >= DATEADD(HOUR, -@hours, GETUTCDATE())
GROUP BY qsq.query_id, qsq.query_hash, qsp.query_plan_hash, qsp.plan_id, qrs.replica_group_id, qsqt.query_sql_text
ORDER BY SUM(qrs.count_executions * qrs.avg_cpu_time / 1000.0) DESC, AVG(qrs.avg_cpu_time / 1000.0) DESC;
SQL Server Management Studio (SSMS) 21 及更高版本中的 查询存储 报表提供 Replica 下拉列表,该下拉列表提供了一种跨各种副本集/角色查看查询存储数据的方法。 此外,在 Object explorer 视图中,如果连接到可读次要副本,查询存储节点将反映查询存储(即READ_CAPTURE)的当前状态。
Azure SQL 数据库 中可读辅助副本遥测数据的查询存储
应用到:Azure SQL 数据库
通过 Azure 诊断设置流式传输查询存储 运行时统计信息 时,会包含两列以帮助识别遥测数据的副本来源:
-
is_primary_b:一个布尔值,用于指示数据源自主副本(true)还是辅助副本(false) -
replica_group_id:对应于副本角色的整数
在跨副本集分析工作负载时,这些列对于澄清指标和性能数据至关重要。 在配置诊断设置以将查询存储运行时统计信息流式传输到 Log Analytics、Event Hubs 或 Azure 存储 时,请确保您的查询和仪表板考虑了这些列,以便按副本角色正确划分数据。 有关配置诊断设置和可用指标的详细信息,请参阅 Azure Monitor 中的 诊断设置。
重要
Azure SQL 数据库 查询性能洞察 (QPI)does not 目前支持该replica_group_id概念。 仪表板中显示的数据将汇总来自所有副本的所有运行时和等待统计数据。
可读二级副本的查询存储性能注意事项
辅助副本用于将查询信息发送回主副本的通道是用于使辅助副本保持最新状态的同一通道。
channel这里意味着什么?
在可用性组(HADR)配置中,副本使用专用传输层相互同步,该传输层承载主副本和辅助副本之间的日志块、确认和状态消息。 这可确保数据一致性和故障转移就绪性。
启用可读次要副本查询存储时,它不会创建单独的网络终结点。 而是在现有传输层上建立新的逻辑通信路径:
对于 Azure SQL 数据库(非超大规模)、Azure SQL 托管实例 和 SQL Server,则使用高可用性和灾难恢复(HADR)Always On 传输层功能。
对于 Azure SQL 数据库 Hyperscale,会使用一种称为“远程 Blob I/O 传输层”的不同传输层。 远程 Blob I/O 传输层是计算节点和日志服务/页服务器之间的通信通道。 远程 Blob I/O 传输层提供可靠的加密通道,用于移动日志记录和数据页。
该路径通过同一加密会话,将查询存储的执行数据(查询文本、执行计划、运行时/等待统计信息)与常规日志记录流量进行多路复用。 该功能拥有独立的捕获和接收队列,可通过从任意副本视角查询 sys.database_query_store_internal_state 视图来查看:
SELECT pending_message_count,
messaging_memory_used_mb
FROM sys.database_query_store_internal_state;
次要副本中的数据保存在主副本的同一查询存储表中,这可能会增加存储需求。 在负载过大的情况下,可能会在传输通道上观察到延迟或回压。 适用于主副本查询存储的同一临时查询捕获限制也适用于次要副本。 有关管理查询存储大小和捕获策略的详细信息和指南,请参阅 在 查询存储 中维护最相关的数据。
负查询 ID/执行计划 ID 的可见性
负 ID 表示在将查询/执行计划持久化到主副本之前,次要副本中用于查询/执行计划的临时内存占位符。
在查询存储数据从可读的次要副本持久化到主副本之前,查询和计划可能会在查询存储的本地内存表示中(MEMORYCLERK_QUERYDISKSTORE_HASHMAP)被分配临时标识符。 查询和执行计划 ID 可能显示为负数,这些值在主副本分配权威标识符之前均作为占位符存在;主副本会在查询存储确定查询满足配置的 捕获模式要求 之后分配该标识符。 如果已设置 自定义捕获策略 ,可以通过查询 sys.database_query_store_options 系统目录视图来查看必须满足的要求。
SELECT query_capture_mode_desc,
capture_policy_execution_count,
capture_policy_total_compile_cpu_time_ms,
capture_policy_total_execution_cpu_time_ms
FROM sys.database_query_store_options;
将查询指定为捕获后,可以持久保存其运行时/等待统计信息和计划,并将本地临时 ID 替换为正 ID。 这还允许您使用执行计划强制或提示功能。