基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
SPM 执行计划管理
更新时间:2026-04-07 20:57:20
SQL Plan Management(SPM)是一种防止计划回退的机制,能够确保新生成的计划在经过验证后才被使用,以保证计划性能不断优化和更新。
功能适用性
目前 OceanBase 数据库社区版暂不支持 SPM 功能。
OceanBase 数据库支持在线 SPM 演进机制,即当发现新生成的计划不在基线中时,就会立即自动启动一个演进任务进行计划演进,这样就可以在用户无需手动干预的情况下自动完成计划演进。
OceanBase 数据库的 SPM 使用 DBA_SQL_PLAN_BASELINES 和 DBA_SQL_MANAGEMENT_CONFIG 视图,以及 DBMS_SPM 系统包来管理执行计划。
SPM 的执行机制
SPM 基于 SQL Plan Baseline 实现,SQL Plan Baseline 是执行计划的一个基线,用于持久化存储已经验证过的执行计划信息(Outline Data 等信息),每个执行计划可对应一个 Plan Baseline,通过该 Plan Baseline 可复现一个执行计划。
OceanBase 数据库计划的演进总是由计划生成触发的,SPM 的执行机制的可以概括为:
- SQL 第一次生成的计划会被默认作为基线并被
ACCEPT。 - 当新的计划存在于计划基线中,并且基线是
FIXED或者不存在其它FIXED计划基线时,直接使用当前计划。 - 当存在可复现的
FIXED基线时,总是优先使用FIXED基线计划,不做计划演进。 - 当不存在可复现的
FIXED基线,但存在可复现的ACCEPTED基线计划,则新计划与基线计划进行演进。 - 如果没有基线计划可以复现,则直接使用新生成的计划。
SPM 的使用限制
OceanBase 数据库的 SPM 具有如下使用限制:
- 处于备份恢复的恢复状态的租户和主备集群的备机无法执行计划演进。
- 系统租户下的 SQL 和 Inner SQL 不能做计划演进。
- SQL 语句包含
INSERT INTO VALUES时不做计划演进。 - 由于演进的结果是暂存在 OBServer 节点的 Local Cache 中,会定期同步到 Inner Table 中,所以任何 OBServer 节点的演进结果对于其它的 OBServer 节点来讲是无法立即感知的。
如何使用 SPM
在项目交付过程中,通常会通过 流量回放验证 SQL 的性能,对性能不达预期的 SQL 进行调优,常见的调优动作包括:调整索引(增减索引)、调整表的分区结构、调整表的分布(打散、迁移、改复制表等)、或者针对特定 SQL 绑定 outline 调优。在完成调优后,建议通过以下步骤开启 SPM(SQL 计划管理),以稳定生产环境的 SQL 执行计划。
基础实践步骤
步骤一:开启 SPM
ALTER SYSTEM SET sql_plan_management_mode = 'OnlineEvolve';
说明:
OnlineEvolve模式允许 SPM 在线演进,动态选择更优计划。- 需确保租户具备
ALTER SYSTEM权限。
步骤二:从 Plan Cache 导入基线计划
适用场景:压测刚结束时,Plan Cache 中仍保留大量 SQL 的执行计划,此时可以直接将 Plan Cache 中的执行计划导入到 SPM 形成基线计划。
存储过程如下:
CALL DBMS_SPM.BATCH_LOAD_PLANS_FROM_CURSOR_CACHE();
其他场景:若压测已结束很久,Plan Cache 中的计划已失效,可通过新一轮压测触发 SPM 自动捕获基线计划。
监控与维护 SPM 演进
通过 DBA_OB_SPM_EVO_RESULT 分析 SQL 演进
视图 DBA_OB_SPM_EVO_RESULT(于 V4.2.5 版本引入,其字段 EVO_PLAN_HASH 和 BASELINE_PLAN_HASH 在 V4.2.5 BP4 版本引入)记录了 SQL 计划的演进过程,包括:
- 触发演进的时间(
START_TIME和END_TIME) - 新计划与基线计划的执行次数、执行时间及 Hash 值
- 演进状态(
success表示演进完成)
SPM 演进情况案例结果输出如下所示:
+----------------------------------+-----------------+---------------------+-------------------+---------------------+-------------------+----------------------+----------------------+
| SQL_ID | NEW_PLAN_BETTER | EVO_PLAN_EXEC_COUNT | EVO_PLAN_CPU_TIME | BASELINE_EXEC_COUNT | BASELINE_CPU_TIME | EVO_PLAN_HASH | BASELINE_PLAN_HASH |
+----------------------------------+-----------------+---------------------+-------------------+---------------------+-------------------+----------------------+----------------------+
| 6E3C88F5D1A97E39A0F7F940EEC6B55E | 1 | 93 | 7077 | 57 | 11958 | 14372305556477891660 | 5690258854010153160 |
| AAD1D09174C0B1512772080AD32DF991 | 0 | 73 | 7339 | 77 | 5819 | 2529381794102860446 | 11087212812447126950 |
| D603D676045B5207E0C5F407E60C4DA7 | 1 | 110 | 1373 | 41 | 5303 | 10177384921167613051 | 3998439253758435947 |
| FEE266BF5572B246FAF2DDA13D309E63 | 0 | 73 | 1355 | 77 | 1274 | 10177384921167613051 | 18341027855757513928 |
| 216171CF20FDA047C669CC68ECFCF34D | 1 | 96 | 1749 | 54 | 5026 | 10177384921167613051 | 3998439253758435947 |
| 45C742A8E022C6603458F203B7ACB7A1 | 1 | 115 | 624 | 35 | 1617 | 2529381794102860446 | 11087212812447126950 |
| D4839A71B942564C1CA3827FFDD4BAA5 | 0 | 88 | 7335 | 62 | 7157 | 3998439253758435947 | 10177384921167613051 |
| D4839A71B942564C1CA3827FFDD4BAA5 | 1 | 95 | 6209 | 55 | 7093 | 3998439253758435947 | 10177384921167613051 |
| 1578C21A38305F8CF1802714B8810EC1 | 0 | 35 | 16223 | 115 | 5075 | 9360560344866912357 | 8291178960580797251 |
| AF9FB704A76392E937E41D0C89D6DD90 | 0 | 75 | 1093 | 75 | 1023 | 10177384921167613051 | 18341027855757513928 |
+----------------------------------+-----------------+---------------------+-------------------+---------------------+-------------------+----------------------+----------------------+
示例
定位并固定性能退化的 SQL 基线计划
通过以下查询定位频繁演进且新计划性能较差的 SQL:
SELECT SQL_ID, BASELINE_PLAN_HASH, COUNT(*),
SUM(BASELINE_EXEC_COUNT), SUM(EVO_PLAN_EXEC_COUNT),
SUM(BASELINE_CPU_TIME), SUM(EVO_PLAN_CPU_TIME)
FROM DBA_OB_SPM_EVO_RESULT
WHERE TYPE = 'OnlineEvolve' AND BASELINE_EXEC_COUNT >= 130
GROUP BY SQL_ID, BASELINE_PLAN_HASH
ORDER BY COUNT(*) DESC LIMIT 10;
查询逻辑说明:
- 筛选条件:
TYPE = 'OnlineEvolve':分析在线演进模式下的记录。BASELINE_EXEC_COUNT >= 130:聚焦高频且基线计划显著更优的演进记录。
结果输出:
+----------------------------------+----------------------+----------+--------------------------+--------------------------+------------------------+------------------------+
| SQL_ID | BASELINE_PLAN_HASH | COUNT(*) | SUM(BASELINE_EXEC_COUNT) | SUM(EVO_PLAN_EXEC_COUNT) | SUM(BASELINE_CPU_TIME) | SUM(EVO_PLAN_CPU_TIME) |
+----------------------------------+----------------------+----------+--------------------------+--------------------------+------------------------+------------------------+
| 074763820FA61A305954C766840FDADC | 14374891169779151928 | 588 | 84066 | 4134 | 896978 | 44750359 |
| 235E3D8A37DE36748D5AB339CA7C55E6 | 18023436715182273474 | 95 | 13366 | 884 | 191699 | 10524837 |
| DF561B4447FF2DD02C14BCA10AF13778 | 18023436715182273474 | 87 | 12244 | 806 | 184878 | 9957498 |
| E8E91ADB581F0BF42F18906475265FC8 | 17605863854413066828 | 42 | 5970 | 330 | 99170 | 5631082 |
| 9E36920D6AA2CD8681210954EDBEE722 | 14714973681921413470 | 39 | 5613 | 237 | 194064 | 9644621 |
| 9C6846E1CA5F255770E0E78F036942D6 | 18023436715182273474 | 27 | 3805 | 245 | 59984 | 2487403 |
| BA3BDA17E30C2A18F276D294949B2F30 | 18023436715182273474 | 20 | 2833 | 167 | 48265 | 3142497 |
| 04CF831409FDEB6648343852A949CF09 | 14374891169779151928 | 16 | 2155 | 245 | 11702 | 611840 |
| E18C32524CD902E2ED56D6171C1E7227 | 18023436715182273474 | 12 | 1709 | 91 | 39279 | 3385151 |
+----------------------------------+----------------------+----------+--------------------------+--------------------------+------------------------+------------------------+
- 回显结果中的字段
count(*)(演进次数):- 第一条记录的
588次说明该 SQL 的基线计划与新计划进行了 588次对比,频繁触发 SPM 演进。
- 第一条记录的
- CPU 时间对比:
- 基线计划总 CPU 时间:
896,978 μs(约 0.9 秒) - 新计划总 CPU 时间:
44,750,359 μs(约 44.75 秒) - 平均 CPU 时间对比:
- 基线计划平均:
896,978 / 84,066 ≈ 10.7 μs - 新计划平均:
44,750,359 / 4,134 ≈ 10,838 μs
- 基线计划平均:
- 新计划的 CPU 时间是基线的 1000倍,性能显著退化
- 基线计划总 CPU 时间:
定位并固定性能退化的 SQL 基线计划
将反复演进,并且新计划性能显著较差的 SQL 的基线计划状态设置为 FIXED,强制 SPM 使用稳定计划。
例如上面的示例中演进次数 588 次 SQL_ID = 074763820FA61A305954C766840FDADC,将基线计划为 BASELINE_PLAN_HASH = 14374891169779151928 设置为 FIXED,SQL 示例如下:
SELECT
DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
'074763820FA61A305954C766840FDADC',
'14374891169779151928'
'fixed',
'YES')
FROM DUAL;
相关文档
SPM 相关视图
DBA_SQL_PLAN_BASELINES 视图记录了 SPM 中 SQL 的计划基线。
DBA_SQL_MANAGEMENT_CONFIG 视图记录了 SPM 中的配置参数。
SPM 相关系统包
MySQL 模式下 SPM 系统包:
- ACCEPT_SQL_PLAN_BASELINE(MySQL 模式)
- ALTER_SQL_PLAN_BASELINE(MySQL 模式)
- CANCEL_EVOLVE_TASK(MySQL 模式)
- CONFIGURE(MySQL 模式)
- DROP_EVOLVE_TASK(MySQL 模式)
- DROP_SQL_PLAN_BASELINE(MySQL 模式)
- LOAD_PLANS_FROM_CURSOR_CACH(MySQL 模式)
Oracle 模式下 SPM 系统包: