Oracle SQL Plan Baseline(SQL 计划基线)
Oracle SQL Plan Baseline(SQL 计划基线)
适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
SQL Plan Baseline 稳定 SQL 执行计划[1]:
优势:
- 防止计划退化
- 仅接受更好计划
- 平滑演进
2. 捕获基线
2.1 自动捕获
ALTER SYSTEM SET optimizer_capture_sql_plan_baselines = TRUE;
-- 默认 FALSE
-- 之后执行的 SQL 自动捕获
-- 第二次执行创建基线
2.2 从游标缓存加载
DECLARE
v_plans PLS_INTEGER;
BEGIN
v_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
sql_id => '&sql_id'
);
END;
/
2.3 从 SQL 调优集加载
DECLARE
v_plans PLS_INTEGER;
BEGIN
v_plans := DBMS_SPM.LOAD_PLANS_FROM_SQLSET(
sqlset_name => 'my_sts'
);
END;
/
2.4 从 AWR 加载
DECLARE
v_plans PLS_INTEGER;
BEGIN
v_plans := DBMS_SPM.LOAD_PLANS_FROM_AWR(
begin_snap => 100,
end_snap => 110
);
END;
/
3. 查看
3.1 基线列表
SELECT
sql_handle,
plan_name,
sql_text,
origin,
enabled,
accepted,
fixed
FROM dba_sql_plan_baselines;
3.2 字段说明
| 字段 | 说明 |
|---|---|
| sql_handle | SQL 标识 |
| plan_name | 计划标识 |
| origin | 来源(AUTO/CAPTURE/MANUAL) |
| enabled | 启用 |
| accepted | 接受 |
| fixed | 固定(优先) |
4. 管理
4.1 启用/禁用
DECLARE
v_result PLS_INTEGER;
BEGIN
v_result := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
sql_handle => '&sql_handle',
plan_name => '&plan_name',
attribute_name => 'ENABLED',
attribute_value => 'NO'
);
END;
/
4.2 接受
DECLARE
v_result PLS_INTEGER;
BEGIN
v_result := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
sql_handle => '&sql_handle',
plan_name => '&plan_name',
attribute_name => 'ACCEPTED',
attribute_value => 'YES'
);
END;
/
4.3 固定
-- Fixed 优先级最高
DECLARE
v_result PLS_INTEGER;
BEGIN
v_result := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
sql_handle => '&sql_handle',
plan_name => '&plan_name',
attribute_name => 'FIXED',
attribute_value => 'YES'
);
END;
/
4.4 删除
-- 单个计划
DECLARE
v_result PLS_INTEGER;
BEGIN
v_result := DBMS_SPM.DROP_SQL_PLAN_BASELINE(
sql_handle => '&sql_handle',
plan_name => '&plan_name'
);
END;
/
-- SQL 所有计划
DECLARE
v_result PLS_INTEGER;
BEGIN
v_result := DBMS_SPM.DROP_SQL_PLAN_BASELINE(
sql_handle => '&sql_handle'
);
END;
/
5. 演进
5.1 自动演进
-- 启用
ALTER SYSTEM SET optimizer_adaptive_plans = TRUE;
-- 参数
EXEC DBMS_SPM.SET_EVOLVE_TASK_PARAMETER(
task_name => 'SYS_AUTO_SPM_EVOLVE_TASK',
parameter => 'ACCEPT_PLANS',
value => 'TRUE'
);
5.2 手动演进
-- 创建任务
DECLARE
v_task VARCHAR2(100);
BEGIN
v_task := DBMS_SPM.CREATE_EVOLVE_TASK(
sql_handle => '&sql_handle'
);
END;
/
-- 执行
EXEC DBMS_SPM.EXECUTE_EVOLVE_TASK(task_name => '&task');
-- 报告
SELECT DBMS_SPM.REPORT_EVOLVE_TASK(task_name => '&task') FROM dual;
-- 接受
EXEC DBMS_SPM.ACCEPT_EVOLVE_TASK(task_name => '&task');
6. 使用基线
6.1 自动使用
-- 默认启用
ALTER SYSTEM SET optimizer_use_sql_plan_baselines = TRUE;
-- CBO 自动选择基线计划
6.2 查看使用
SELECT * FROM v$sql
WHERE sql_plan_baseline IS NOT NULL;
7. 导出/导入
7.1 创建 Stage 表
EXEC DBMS_SPM.CREATE_STGTAB_BASELINE('STAGE_TAB');
7.2 打包
DECLARE
v_count PLS_INTEGER;
BEGIN
v_count := DBMS_SPM.PACK_STGTAB_BASELINE(
staging_table_name => 'STAGE_TAB',
sql_handle => '&sql_handle'
);
END;
/
7.3 导出/导入
expdp system/pwd TABLES=stage_tab ...
impdp system/pwd TABLES=stage_tab ...
7.4 解包
DECLARE
v_count PLS_INTEGER;
BEGIN
v_count := DBMS_SPM.UNPACK_STGTAB_BASELINE(
staging_table_name => 'STAGE_TAB'
);
END;
/
8. 应用场景
8.1 升级稳定
-- 升级前捕获基线
ALTER SYSTEM SET optimizer_capture_sql_plan_baselines = TRUE;
-- 业务运行
-- 升级后保留计划
8.2 防止退化
-- 自动捕获
-- 新计划未接受
-- 测试后接受
8.3 固定计划
-- 锁定最优计划
EXEC DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
sql_handle => '&sql_handle',
attribute_name => 'FIXED',
attribute_value => 'YES'
);
9. 常见坑与排错
9.1 基线不使用
-- 1. 检查 ENABLED
-- 2. 检查 ACCEPTED
-- 3. 检查参数
SHOW PARAMETER optimizer_use_sql_plan_baselines
9.2 计划变化
-- 查看新计划
SELECT * FROM dba_sql_plan_baselines WHERE accepted = 'NO';
-- 测试接受
9.3 性能变差
-- 1. 检查 fixed
-- 2. 删除坏基线
-- 3. 重新捕获
10. 最佳实践
- 升级前捕获:稳定
- 自动捕获开启:保险
- 测试后接受:安全
- 关键 SQL 固定:稳定
- 定期演进:优化
- 导出备份:迁移
- 监控基线:状态
- 结合 SQL Profile:自动
- 文档化:维护
- 测试验证:效果
11. 参考资料
[1] Oracle Database SQL Tuning Guide 19c, “SQL Plan Baselines” https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/sql-plan-baselines.html