SPM 包含如下过程:

  1. 计划捕获。

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

  1. 计划演进。

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

  1. 计划选择。

使用如下系统变量及 package 能够控制 SPM 的使用。

optimizer_capture_sql_plan_baselines

  • optimizer_capture_sql_plan_baselines 为 true 时,对于新生成的计划,如果该 SQL 没有对应的 Plan Baseline,则将该计划加入到 SQL Plan Baseline;如果该 SQL 已有 Plan Baseline 且与新计划不同, 则会触发计划演进进行验证,确定是否需要将新计划替换旧的 Plan Baseline;
  • optimizer_capture_sql_plan_baselines 为 false 时, 则不再自动捕获新计划到 Plan Baseline 中。

optimizer_use_sql_plan_baselines

  • 如果 optimizer_use_sql_plan_baselines 为 true, 在新生成计划时,优化器会优先使用 Plan Baseline 计划,对于新计划则验证后通过后才使用;

optimizer_capture_sql_plan_baselines 和 optimizer_use_sql_plan_baselines 设置说明

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

LOAD_PLANS_FROM_CURSOR_CACHE

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

  1. v_load_plans number;
  2. BEGIN
  3. v_load_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
  4. sql_id => '529F6E6454EF579C7CC265D1F6131D70',
  5. plan_hash_value => 13388268709115914355,
  6. );
  7. END;
  8. /

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. attribute_name => 'fixed',
  6. attribute_value => 'YES'
  7. );
  8. /

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'
  7. );
  8. /