OceanBase 执行计划管理
SQL Plan Management(SPM)是一种稳定执行计划、控制计划演进的机制,确保新生成的计划在经过验证后才能使用,保证计划性能朝好的方向不断更新。
SPM 基于 SQL Plan Baseline 实现,SQL Plan Baseline 是执行计划的一个基线,持久化存储已经验证过的执行计划的信息(outline_data 等信息),每个执行计划可对应一个 Plan Baseline,通过该 Plan Baseline 可复现一个执行计划。
SPM 包含如下过程:
-
计划捕获。
对于新生成的计划,如果 SQL Plan Baseline 为空,则直接加入 SQL Plan Baseline,否则通过演进验证新生成计划比 SQL Plan Baseline 中计划性能更优后加入 SQL Plan Baseline,并删除旧的 Plan Baseline。
-
计划演进。
相同 SQL 新捕获的计划如果和 SQL Plan Baseline 中计划不一样,则通过流量灰度验证新计划性能是否比以前验证过的计划更优。如果更优,则将新计划加入 SQL Plan Baseline,并执行新计划,否则仍使用旧计划。
-
计划选择。
在优化器新生成计划时,会查看 SQL Plan Baseline 是否有已验证的计划,如果有,则优先使用已验证计划,新计划需要通过演进验证后再使用。
SPM 的系统变量
SPM 使用如下系统变量和系统包对执行计划进行管理:
系统变量 |
取值 |
解释 |
---|---|---|
optimizer_capture_sql_plan_baselines |
true |
对于新生成的计划,如果该 SQL 没有对应的 Plan Baseline,则将该计划加入到 SQL Plan Baseline;如果已有 Plan Baseline 且与新计划不同,则会触发计划演进进行验证,确定是否需要将新计划替换老的 Plan Baseline。 |
false |
再自动捕获新计划到 Plan Baseline 中。 |
|
optimizer_use_sql_plan_baselines |
true |
在新生成计划时,优化器会优先使用 Plan Baseline 计划,对于新的不同计划则验证后通过后才使用。 |
false |
在新生成计划时,不在考虑 Plan Baseline 中计划,直接使用优化器新生成计划并执行。 |
设置说明如下:
optimizer_capture_sql_plan_baselines 的取值 |
optimizer_use_sql_plan_baselines 的取值 |
说明 |
---|---|---|
True |
True |
计划捕获和演进均打开,优化器会使用 Plan Baseline 计划。 |
True |
False |
Plan Baseline 中无计划时会捕获计划到 Plan Baseline,不演进,优化器不考虑 Plan Baseline 计划,使用新生成计划。 |
False |
True |
不捕获计划到 Plan Baseline, 优化器会使用 Plan Baseline 计划,如果 SQL Plan Baseline 没有对应计划,则使用新生成计划。 |
False |
False |
不捕获计划,不演进,优化器不使用 Plan Baseline 计划,使用新生成的计划。 |
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 数据库内部表。
DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
sql_id IN VARCHAR2,
plan_hash_value IN NUMBER := NULL,
fixed IN VARCHAR2 := 'NO',
enabled IN VARCHAR2 := 'YES')
RETURN PLS_INTEGER;
参数解释如下:
参数 |
解释 |
---|---|
sql_id |
SQL 的唯一标识。 |
plan_hash_value |
plan 的唯一标识。如果为空,则处理 sql_id 下的所有计划。 |
fixed |
加入到 SQL Plan Baseline 后是否将该计划固化。固化后以后优化器会直接选择该计划,不再捕获和演进计划。 |
enabled |
优化器是否可以使用该 Plan Baseline。 |
如下例所示:
DECLARE
v_load_plans number;
BEGIN
v_load_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
sql_id => '529F6E6454EF579C7CC265D1F6131D70',
plan_hash_value => 13388268709115914355);
END;
/
ALTER_SQL_PLAN_BASELINE
ALTER_SQL_PLAN_BASELINE 用于修改 Plan Baseline 中某些属性。语法如下:
DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
sql_handle IN VARCHAR2 := NULL,
plan_name IN VARCHAR2 := NULL,
attribute_name IN VARCHAR2,
attribute_value IN VARCHAR2)
RETURN PLS_INTEGER;
参数解释如下:
参数 |
解释 |
---|---|
sql_handle |
SQL 的唯一标识。先用 sql_id 代替。 |
plan_name |
plan 的唯一标识。先使用 plan_hash_value 代替。 |
attribute_name |
需要更改的字段名。OceanBase 数据库支持修改 enabled 和 fixed 字段。 |
attribute_value |
更改后的值。 |
如下示例所示,将某个 Plan Baseline 固化后该 SQL 仅使用该计划:
DECLARE
v_alter_plans number;
BEGIN
v_alter_plans := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
sql_handle => '529F6E6454EF579C7CC265D1F6131D70',
plan_name => '3388268709115914355',
attribute_name => 'fixed',
attribute_value => 'YES' );
END;
/
DROP_SQL_PLAN_BASELINE
DROP_SQL_PLAN_BASELINE 用于删掉某个 Plan Baseline。语法如下:
DBMS_SPM.DROP_SQL_PLAN_BASELINE (
sql_handle IN VARCHAR2 := NULL,
plan_name IN VARCHAR2 := NULL)
RETURN PLS_INTEGER;
示例如下:
DECLARE
v_drop_plans number;
BEGIN
v_drop_plans := DBMS_SPM.DROP_SQL_PLAN_BASELINE(
sql_handle => '529F6E6454EF579C7CC265D1F6131D70',
plan_name => '3388268709115914355' );
END;
/
更多建议: