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_handleSQL 标识
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. 最佳实践

  1. 升级前捕获:稳定
  2. 自动捕获开启:保险
  3. 测试后接受:安全
  4. 关键 SQL 固定:稳定
  5. 定期演进:优化
  6. 导出备份:迁移
  7. 监控基线:状态
  8. 结合 SQL Profile:自动
  9. 文档化:维护
  10. 测试验证:效果

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