SPM 基于 SQL Plan Baseline 实现,SQL Plan Baseline 是执行计划的一个基线,持久化存储已经验证过的执行计划的信息(outline_data 等信息),每个执行计划可对应一个 Plan Baseline,通过该 Plan Baseline 可复现一个执行计划。

SPM 包含如下过程:

  1. 计划捕获。

    对于新生成的计划,如果 SQL Plan Baseline 为空,则直接加入 SQL Plan Baseline,否则通过演进验证新生成计划比 SQL Plan Baseline 中计划性能更优后加入 SQL Plan Baseline,并删除旧的 Plan Baseline。

  2. 计划演进。

    相同 SQL 新捕获的计划如果和 SQL Plan Baseline 中计划不一样,则通过流量灰度验证新计划性能是否比以前验证过的计划更优。如果更优,则将新计划加入 SQL Plan Baseline,并执行新计划,否则仍使用旧计划。

  3. 计划选择。

    在优化器新生成计划时,会查看 SQL Plan Baseline 是否有已验证的计划,如果有,则优先使用已验证计划,新计划需要通过演进验证后再使用。

SPM 使用如下系统变量和系统包对执行计划进行管理:

DBMS_SPM

DBMS_SPM 是用于操作 SPM 的命令包,可支持加载、更改以及删除 Plan Baseline 信息。

LOAD_PLANS_FROM_CURSOR_CACHE

LOAD_PLANS_FROM_CURSOR_CACHE 用于将 plan cache 中执行计划对应的 Plan Baseline 信息加载到 _ _all_tenant_plan_baseline 表中。语法如下:

说明

_ _all_tenant_plan_baseline 为 OceanBase 数据库内部表。

参数解释如下:

如下例所示:

  1. v_load_plans number;
  2. BEGIN
  3. sql_id => '529F6E6454EF579C7CC265D1F6131D70',
  4. plan_hash_value => 13388268709115914355);
  5. END;
  6. /

ALTER_SQL_PLAN_BASELINE

ALTER_SQL_PLAN_BASELINE 用于修改 Plan Baseline 中某些属性。语法如下:

参数解释如下:

如下示例所示,将某个 Plan Baseline 固化后该 SQL 仅使用该计划:

  1. v_alter_plans number;
  2. BEGIN
  3. v_alter_plans := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
  4. sql_handle => '529F6E6454EF579C7CC265D1F6131D70',
  5. plan_name => '3388268709115914355',
  6. attribute_value => 'YES' );
  7. /

DROP_SQL_PLAN_BASELINE

DROP_SQL_PLAN_BASELINE 用于删掉某个 Plan Baseline。语法如下:

  1. DECLARE
  2. v_drop_plans number;
  3. BEGIN
  4. v_drop_plans := DBMS_SPM.DROP_SQL_PLAN_BASELINE(
  5. sql_handle => '529F6E6454EF579C7CC265D1F6131D70',
  6. plan_name => '3388268709115914355' );