首批通过分布式安全可靠测评,为关键业务系统打造
AP 查询路由判定规则
更新时间:2026-06-23 18:10:34
在 OceanBase 数据库 V4.6.0 及以上 版本中,若租户已配置 列存副本(C 副本),并启用了由 ap_query_route_policy 等变量控制的列存副本自动选择,优化器会按 固定规则 判断:一条语句的只读部分是否 尝试 在 C 副本上规划或执行。
系统变量默认值、如何开启或关闭能力、读写一致性设置 等操作说明,参见 部署与使用列存副本。
如何理解判定规则
您可以将 AP 查询路由判定规则理解为两层约束条件,一层是基本条件,一层是策略分支:
第一层:基本条件
必须 全部满足,系统才会将语句纳入列存副本自动选择的考量范围。
任一条不满足,则不会按该能力尝试列存路径。这与
ap_query_route_policy = OFF不同:OFF是 整体关闭 列存副本自动选择;不满足基本条件则是 本条 SQL 语句 不在判定范围内。第二层:策略分支(
ap_query_route_policy)在基本条件全部满足之后,由
ap_query_route_policy设置为FORCE/AUTO/OFF决定 是否还需要 弱读、并行、代价阈值等额外条件:FORCE:在基本条件全部满足的前提下,直接尝试 列存副本侧计划,不再 要求弱读、并行或代价超过阈值等 AUTO 下的触发项。AUTO(默认):在基本条件全部满足的前提下,还须 至少满足一条 AUTO 下的触发条件,才会进一步尝试列存副本侧计划。OFF:不启用列存副本自动选择,行为与未引入该能力时一致(按行存等默认路径规划)。
综上所述,先满足基本条件,再看策略;AUTO 在基本条件全部满足之后,还要求至少一条触发条件成立,才会尝试列存侧规划;FORCE 在基本条件全部满足之后不再 要求这些触发项。
基本条件(须同时满足)
只有下列条件 同时成立,语句才可能进入后续的 FORCE / AUTO 分支:
| 条件 | 说明 |
|---|---|
| 单语句事务 | 语句运行在 单语句事务 语义下:例如未显式 BEGIN/START TRANSACTION 的独立 SELECT;autocommit 开启时的单条 DML 等。显式事务内 的语句通常不满足本条,不会按此套规则尝试列存自动选择路径。 |
| 租户具备列存副本 | 租户 LOCALITY 中已配置 C 副本,且列存副本处于可提供读服务的状态(含行转列、合并等就绪情况,详见 部署与使用列存副本)。 |
| 未关闭自动选择 | 会话/全局的 ap_query_route_policy 以及本条 SQL 上的 Hint 均未设为 OFF。 |
| 访问用户基表 | 执行计划涉及 至少一张用户基表。不涉及用户基表的语句(如 SELECT 1、SELECT NOW())不满足本条。 |
| 与回退策略一致 | ap_query_replica_fallback 控制列存不可用或无法生成列存计划时是否回退行存;不 单独作为是否尝试列存的正向条件,但运维上需与副本可用性一并考虑,避免出现期望走列存但总在回退的现象。 |
AUTO 下的触发条件(满足任一即可)
在 ap_query_route_policy = AUTO 且 全部基本条件已满足 时,满足下列 任意一条,会触发 尝试 列存副本侧计划:
| 触发项 | 说明 |
|---|---|
| 弱读 | 当前语句使用弱一致性读,例如会话级 ob_read_consistency = 'weak'。读级别详见 ob_read_consistency。 |
| 并行执行 | 计划中 SELECT 相关部分 的并行度 大于 1(含 PARALLEL Hint 或优化器自动并行等,以实际计划为准)。 |
| 代价超过阈值 | 单并行度 下,SELECT 相关部分的估算代价 高于 ap_query_cost_threshold。含多个 SELECT 片段的语句(如部分 UNION ALL、嵌套子查询等),代价 累加规则以当前版本为准。 |
在 ap_query_route_policy = FORCE 时:不需要 满足上表中的弱读、并行或代价条件;只要 基本条件 全部满足,即可在允许的前提下尝试列存路径。
与哪些设置相互影响
判定时会直接依赖或需要一并留意的项包括:
ap_query_route_policy:决定是 关闭、AUTO(带触发条件) 还是 FORCE(不依赖触发条件)。ob_read_consistency:弱读是 AUTO 下常见触发项之一。ap_query_cost_threshold:AUTO 下用于代价超过阈值触发项。ap_query_replica_fallback:不决定是否尝试列存,但影响列存不可用或无法生成列存计划时是否 回退行存。
会话级 ob_route_policy 等与副本类型相关的变量,可参考 ob_route_policy 及 部署与使用列存副本。
不走列存自动选择路径的情况
| 情况 | 说明 |
|---|---|
ap_query_route_policy = OFF |
不选择走列存副本路径,按行存等默认路径规划。 |
| 某一基本条件不满足(任一基本条件未满足) | 例如显式事务内、无用户表、无 C 副本等。 |
AUTO 且三条触发条件均不成立 |
非弱读、无并行、SELECT 部分代价未超 ap_query_cost_threshold,则通常仍按行存等路径规划(典型如简单点查、小结果集限幅查询)。 |
示例说明
FORCE:满足基本条件即可在计划中体现列存访问
obclient> SET ap_query_route_policy = 'FORCE';
obclient> EXPLAIN SELECT * FROM t1 LIMIT 1;
计划中若出现 列存侧扫描算子(含 COLUMN TABLE FULL SCAN),说明已尝试走列存副本路径。
AUTO:并行度大于 1 时可能触发列存路径
obclient> SET ap_query_route_policy = 'AUTO';
obclient> EXPLAIN SELECT /*+parallel(4)*/ COUNT(*) FROM t1;
AUTO:代价与阈值的关系
当查询计划中 SELECT 部分的代价超过 ap_query_cost_threshold 系统变量设置的阈值(默认值为 200000)时,查询会被识别为 AP 查询。将 ap_query_cost_threshold 调低,复杂查询更易触发列存侧计划重试;调高 则更多查询保留在行存计划。
- 设置较低代价阈值示例:
obclient> SET ap_query_route_policy = 'AUTO';
-- 设置代价阈值为 50000。
obclient> SET ap_query_cost_threshold = 50000;
-- 复杂查询(代价超过阈值)自动路由到列存副本
obclient> EXPLAIN SELECT * FROM t1, t2 WHERE t1.c1 = t2.c1;
- 设置较高代价阈值示例(代价未超阈值,不触发列存路径路由):
obclient> SET ap_query_route_policy = 'AUTO';
-- 将阈值调高后:若 SELECT 部分估算代价 **低于** 新阈值,代价未超阈值,不触发列存路径路由。
obclient> SET ap_query_cost_threshold = 1000000;
obclient> EXPLAIN SELECT * FROM t1, t2 WHERE t1.c1 = t2.c1;
若计划中仍为 行存扫描算子(如 TABLE FULL SCAN)、且未出现列存侧扫描算子,说明本次未因代价触发列存自动选择。
无用户表:不满足基本条件
obclient> EXPLAIN SELECT 1;
此类计划通常不包含用户表访问,不会纳入列存副本自动选择的判定流程。