---
title: "执行计划管理 - OceanBase 数据库 V4.4.1 | OceanBase 文档中心"
description: 执行计划管理 SQL Plan Management（SPM）是一种防止计划回退的机制，能够确保新生成的计划在经过验证后才被使用，以保证计划性能不断优化和更新。 功能适用性 目前 OceanBase 数据库社区版暂不支持 SPM 功能。 OceanBase 数据库支持在线 SPM 演进机制，即当发现新生成的计划不在基…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.4.1

# 执行计划管理

更新时间：2025-12-02 17:54:03

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.4.1/zh-CN/700.reference/1000.performance-tuning-guide/500.sql-optimization/400.sql-optimization/700.manage-execution-plans/300.sql-execution-plan-management-spm.md)  

SQL Plan Management（SPM）是一种防止计划回退的机制，能够确保新生成的计划在经过验证后才被使用，以保证计划性能不断优化和更新。

#### 功能适用性

目前 OceanBase 数据库社区版暂不支持 SPM 功能。

OceanBase 数据库支持在线 SPM 演进机制，即当发现新生成的计划不在基线中时，就会立即自动启动一个演进任务进行计划演进，这样就可以在用户无需手动干预的情况下自动完成计划演进。

OceanBase 数据库的 SPM 使用 `DBA_SQL_PLAN_BASELINES` 和 `DBA_SQL_MANAGEMENT_CONFIG` 视图，以及 `DBMS_SPM` 系统包来管理执行计划。

## SPM 的执行机制

SPM 基于 SQL Plan Baseline 实现，SQL Plan Baseline 是执行计划的一个基线，用于持久化存储已经验证过的执行计划信息（Outline Data 等信息），每个执行计划可对应一个 Plan Baseline，通过该 Plan Baseline 可复现一个执行计划。

OceanBase 数据库计划的演进总是由计划生成触发的，SPM 的执行机制的可以概括为：

1. SQL 第一次生成的计划会被默认作为基线并被 `ACCEPT`。
 2. 当新的计划存在于计划基线中，并且基线是 `FIXED` 或者不存在其它 `FIXED` 计划基线时，直接使用当前计划。
 3. 当存在可复现的 `FIXED` 基线时，总是优先使用 `FIXED` 基线计划，不做计划演进。
 4. 当不存在可复现的 `FIXED`基线，但存在可复现的 `ACCEPTED` 基线计划，则新计划与基线计划进行演进。
 5. 如果没有基线计划可以复现，则直接使用新生成的计划。

## SPM 的使用限制

OceanBase 数据库的 SPM 具有如下使用限制：

- 处于备份恢复的恢复状态的租户和主备集群的备机无法执行计划演进。
 - 系统租户下的 SQL 和 Inner SQL 不能做计划演进。
 - SQL 语句包含 `INSERT INTO VALUES` 时不做计划演进。
 - 由于演进的结果是暂存在 OBServer 节点的 Local Cache 中，会定期同步到 Inner Table 中，所以任何 OBServer 节点的演进结果对于其它的 OBServer 节点来讲是无法立即感知的。

## SPM 相关视图

### DBA_SQL_PLAN_BASELINES

`DBA_SQL_PLAN_BASELINES` 视图记录了 SPM 中 SQL 的计划基线。该视图各字段的含义如下表所示。

| **字段名称** | **数据类型** | **是否为 NULL** | **说明** |
| --- | --- | --- | --- |
| SIGNATURE | VARCHAR2(128) | NOT NULL | 由归一化的 SQL 产生的 SQL 唯一标识符（这个字段的类型与 Oracle 不兼容）。 |
| SQL_HANDLE | VARCHAR2(128) | NOT NULL | 唯一的文本形式的 SQL 表示。 |
| SQL_TEXT | CLOB | NOT NULL | 未归一化的 SQL 文本。 |
| PLAN_NAME | VARCHAR2(128) | NOT NULL | 唯一的文本形式的计划标识符。 |
| CREATOR | VARCHAR2(128) |  | 创建这条计划基线的用户名称。 |
| ORIGIN | VARCHAR2(14) |  | 计划基线的创建方式，如下：   - `MANUAL-LOAD` - `AUTO-CAPTURE` - `MANUAL-SQLTUNE` - `AUTO-SQLTUNE` |
| PARSING_SCHEMA_NAME | VARCHAR2(128) |  | 恒为 NULL。 |
| DESCRIPTION | VARCHAR2(500) |  | 计划基线的说明。 |
| VERSION | VARCHAR2(64) |  | 计划基线创建时的数据库版本。 |
| CREATED | TIMESTAMP(6) | NOT NULL | 计划基线的创建时间。 |
| LAST_MODIFIED | TIMESTAMP(6) |  | 计划基线上次的修改时间。 |
| LAST_EXECUTED | TIMESTAMP(6) |  | 计划基线上次的执行时间。 |
| LAST_VERIFIED | TIMESTAMP(6) |  | 计划基线上次的验证时间。 |
| ENABLED | VARCHAR2(3) |  | 计划基线是启用的（'YES'）还是禁用的（'NO'）。 |
| ACCEPTED | VARCHAR2(3) |  | 计划基线是被采纳的（'YES'）还是未被采纳的（'NO'）。 |
| FIXED | VARCHAR2(3) |  | 计划基线是固定的（'YES'）还是非固定的（'NO'）。 |
| REPRODUCED | VARCHAR2(3) |  | 计划基线是可复现的（'YES'）还是不可复现的（'NO'）。 |
| AUTOPURGE | VARCHAR2(3) |  | 计划基线是自动清理的（'YES'）还是非自动清理的（'NO'）。 |
| ADAPTIVE | VARCHAR2(3) |  | 由 SPM 自动捕获的计划基线是否已经是适应的。 |
| OPTIMIZER_COST | NUMBER |  | 计划基线创建时优化器估计的计划代价。 |
| MODULE | VARCHAR2(64) |  | 恒为 NULL。 |
| ACTION | VARCHAR2(64) |  | 恒为 NULL。 |
| EXECUTIONS | NUMBER |  | 计划基线创建时计划的执行次数。 |
| ELAPSED_TIME | NUMBER |  | 计划基线创建时计划的总耗时。 |
| CPU_TIME | NUMBER |  | 计划基线创建时计划的总 CPU 时间。 |
| BUFFER_GETS | NUMBER |  | 恒为 NULL。 |
| DISK_READS | NUMBER |  | 恒为 NULL。 |
| DIRECT_WRITES | NUMBER |  | 恒为 NULL。 |
| ROWS_PROCESSED | NUMBER |  | 恒为 NULL。 |
| FETCHES | NUMBER |  | 恒为 NULL。 |
| END_OF_FETCH_COUNT | NUMBER |  | 恒为 NULL。 |

### DBA_SQL_MANAGEMENT_CONFIG

`DBA_SQL_MANAGEMENT_CONFIG` 视图记录了 SPM 中的配置参数。该视图各字段的含义如下表所示。

| **字段名称** | **数据类型** | **是否为NULL** | **说明** |
| --- | --- | --- | --- |
| PARAMETER_NAME | VARCHAR2(128) | NOT NULL | 配置参数的名字。如下：   - `SPACE_BUDGET_PERCENT` - `PLAN_RETENTION_WEEKS` |
| PARAMETER_VALUE | NUMBER | NOT NULL | 配置参数的值。 |
| LAST_MODIFIED | TIMESTAMP(6) |  | 参数值上次更新的时间。 |
| MODIFIED_BY | VARCHAR2(128) |  | 参数值上次由谁更新的。 |

## DBMS_SPM 系统包

`DBMS_SPM` 系统包用于管理 SQL 计划，支持加载、更改以及删除 Plan Baseline 信息。

下表列出了 OceanBase 数据库当前版本所支持的 DBMS_SPM 子程序和简要描述。

| **子程序** | **描述** |
| --- | --- |
| ACCEPT_SQL_PLAN_BASELINE | 根据演进计划的结果接受一个计划作为基线。 |
| ALTER_SQL_PLAN_BASELINE | 修改基线中一个或一组计划的属性。返回值表示被修改的基线数量。 |
| CANCEL_EVOLVE_TASK | 取消一个正在演进的任务。 |
| CONFIGURE | 设置 SPM 的一些参数。 |
| DROP_EVOLVE_TASK | 丢弃一个演进任务。 |
| DROP_SQL_PLAN_BASELINE | 丢弃一个或多个计划基线。 |
| LOAD_PLANS_FROM_CURSOR_CACH | 从 Cursor Cache 中读取一条或多条 SQL 计划作为计划基线。 |

### ACCEPT_SQL_PLAN_BASELINE

`ACCEPT_SQL_PLAN_BASELINE` 过程用于根据演进计划的结果接受一个计划作为基线。

#### 语法

Oracle 模式下的语法如下：

```sql
DBMS_SPM.ACCEPT_SQL_PLAN_BASELINE  (
    sql_handle        IN VARCHAR,
    plan_name         IN VARCHAR := NULL);

```

MySQL 模式下的语法如下：

```sql
DBMS_SPM.ACCEPT_SQL_PLAN_BASELINE  (
     database_name     VARCHAR(65535),
     sql_handle        VARCHAR(65535),
     plan_name         VARCHAR(65535) DEFAULT NULL);

```

#### 参数说明

| **参数名称** | **说明** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| sql_handle | SQL 的标识符，也就是 `SQL_ID`。 |
| plan_name | 计划的名称，也就是 Plan Hash Value。如果值为 `NULL`，表示接受一个 SQL 所有正在演进的计划。 |

#### 示例

```sql
DECLARE
  v_accept_plans NUMBER;
BEGIN
  v_accept_plans := DBMS_SPM.ACCEPT_SQL_PLAN_BASELINE(
     sql_handle => '529F6E6454EF579C7CC265D1F6131D70',
     plan_name => '3388268709115914355'
     );
END;
/

```

### ALTER_SQL_PLAN_BASELINE

`ALTER_SQL_PLAN_BASELINE` 函数用于修改基线中一个或一组计划的属性。返回值表示被修改的基线数量。

```sql
DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
  sql_handle        IN VARCHAR,
  plan_name         IN VARCHAR := NULL,
  attribute_name    IN VARCHAR,
  attribute_value   IN VARCHAR
)
RETURN PLS_INTEGER;

```

```sql
DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
  database_name     VARCHAR(65535),
  sql_handle        VARCHAR(65535),
  plan_name         VARCHAR(65535) DEFAULT NULL,
  attribute_name    VARCHAR(65535),
  attribute_value   VARCHAR(65535)
)
RETURN DECIMAL;

```

#### 参数说明

| **参数名称** | **说明** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| sql_handle | SQL 的标识符，也就是 `SQL_ID`。 |
| plan_name | 计划的名称，也就是 Plan Hash Value。如果值为 `NULL`，表示接受一个 SQL 所有正在演进的计划。 |
| attribute_name | 计划的属性名称。请参见 **属性说明**。 |
| attribute_value | 计划的属性值。请参见 **属性说明**。 |

#### 属性说明

| **属性名称** | **可取的属性值** | **描述** |
| --- | --- | --- |
| enabled | 'YES' 或 'NO' | 'YES' 表示计划基线是有效的。最终计划基线是否会被使用取决于是否被接受。 |
| fixed | 'YES' 或 'NO' | 'YES' 表示优先使用当前计划基线，并且**不进行自动演进**。 |
| autopurge | 'YES' 或 'NO' | 'YES' 表示计划基线一段时候没有使用后会被自动淘汰；'NO' 表示计划基线永不淘汰。 |
| plan_name | 字符串，最多 30 个字符。 | 计划的名称。 |
| description | 字符串，最多 500 个字节。 | 计划的描述。 |

#### 示例

将某个 Plan Baseline 固化后该 SQL 仅使用该计划。

```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;
/

```

### CANCEL_EVOLVE_TASK

`CANCEL_EVOLVE_TASK` 过程用于取消一个正在演进的任务。

#### 语法

Oracle 模式下的语法：

```sql
DBMS_SPM.CANCEL_EVOLVE_TASK (
 task_name INVARCHAR2);

```

MySQL 模式下的语法：

```sql
DBMS_SPM.CANCEL_EVOLVE_TASK  (
  database_name     VARCHAR(65535),
  task_name         VARCHAR(65535));

```

#### 参数说明

| **参数名称** | **描述** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| task_name | 任务名称，即当前 OceanBase 数据库中使用 `SQL_ID` 所表示的演进任务名称。 |

#### 示例

```sql
BEGIN
  DBMS_SPM.CANCEL_EVOLVE_TASK ('SYS_AUTO_SPM_EVOLVE_TASK');
END;

```

### CONFIGURE

`CONFIGURE` 过程用于设置 SPM 的一些参数。

```sql
DBMS_SPM.CONFIGURE (
    parameter_name    IN VARCHAR2,
    parameter_value   IN NUMBER
  );

```

```sql
DBMS_SPM.CONFIGURE (
    database_name     VARCHAR(65535),
    parameter_name    VARCHAR(65535),
    parameter_value   DECIMAL
  );

```

#### 参数说明

| **参数名称** | **说明** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| parameter_name | 要设置的参数名称。请参见 **SPM 参数说明**。 |
| parameter_value | 要设置的参数值。请参见 **SPM 参数说明**。 |

#### SPM 参数说明

| SPM 参数名称 | **描述** | **可取的参数值** | **默认值** |
| --- | --- | --- | --- |
| space_budget_percent | 用于设置 SPM 的 SYSAUX 空间最大百分比。 | 1，2，...，50 | 10 |
| plan_retention_weeks | 设置计划几周后未被使用会被自动淘汰掉。 | 5，6，...，523 | 53 |

#### 示例

设置计划 20 周后未被使用会被自动淘汰掉。

```sql
BEGIN
  DBMS_SPM.CONFIGURE ('plan_retention_weeks', 20);
END;

```

### DROP_EVOLVE_TASK

`DROP_EVOLVE_TASK` 过程用于丢弃一个演进任务。

```sql
DBMS_SPM.DROP_EVOLVE_TASK  (
  task_name        IN  VARCHAR2);

```

```sql
DBMS_SPM.DROP_EVOLVE_TASK  (
  database_name     VARCHAR(65535),
  task_name         VARCHAR(65535));

```

#### 参数说明

| **参数名称** | **说明** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| task_name | 任务名称，即当前 OceanBase 数据库中使用 `SQL_ID` 所表示的演进任务名称。 |

#### 示例

```sql
BEGIN
  DBMS_SPM.DROP_EVOLVE_TASK ('SYS_AUTO_SPM_EVOLVE_TASK');
END;

```

### DROP_SQL_PLAN_BASELINE

`DROP_SQL_PLAN_BASELINE` 函数用于用于丢弃一个或多个计划基线。

```sql
DBMS_SPM.DROP_SQL_PLAN_BASELINE (
  sql_handle     IN VARCHAR2,
  plan_name      IN VARCHAR2 := NULL
)
RETURN PLS_INTEGER;

```

```sql
DBMS_SPM.DROP_SQL_PLAN_BASELINE (
  database_name     VARCHAR(65535),
  sql_handle        VARCHAR(65535),
  plan_name         VARCHAR(65535) DEFAULT NULL
)
RETURN DECIMAL;

```

#### 参数说明

| **参数名称** | **说明** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| sql_handle | SQL 的标识符，也就是 `SQL_ID`。执行计划用于标识 SQL 语句的句柄（Handle）。当查询某条 SQL 语句的特定执行计划时，在存在多条相似 SQL 时，可通过 sql_handle 精准指定目标语句。 |
| plan_name | 执行计划的名称，也就是 Plan Hash Value。如果值为 `NULL`，表示接受一个 SQL 所有正在演进的计划。 |

#### 示例

```sql
DECLARE
  v_drop_plans number;
BEGIN
  v_drop_plans := DBMS_SPM.DROP_SQL_PLAN_BASELINE(
     sql_handle => '529F6E6454EF579C7CC265D1F6131D70',
     plan_name => '3388268709115914355' );
END;
/

```

### LOAD_PLANS_FROM_CURSOR_CACHE

`LOAD_PLANS_FROM_CURSOR_CACHE` 函数用于用于从 Plan Cache 中读取一条或多条 SQL 的计划作为计划基线。

```sql
DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
  sql_id              IN VARCHAR,
  plan_hash_value     IN NUMBER   := NULL,
  fixed               IN VARCHAR  := 'NO',
  enabled             IN VARCHAR  := 'YES'
)
RETURN PLS_INTEGER;

```

```sql
DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
  database_name     VARCHAR(65535),
  sql_id            VARCHAR(65535),
  plan_hash_value   DECIMAL DEFAULT NULL,
  is_fixed          VARCHAR(65535) DEFAULT 'NO',
  enabled           VARCHAR(65535) DEFAULT 'YES'
)
RETURN DECIMAL;

```

#### 参数说明

| **参数名称** | **说明** |
| --- | --- |
| database_name | 数据库名称，仅 MySQL 模式下需要指定该参数。 |
| sql_id | 要加载的 `SQL_ID`。 |
| plan_hash_value | 要加载的计划的 Plan Hash Value。如果值为 `NULL`，加载 Plan Cache 中指定 SQL 的所有计划作为计划基线。 |
| is_fixed | 加载的计划基线的 `is_fixed` 属性。 |
| enabled | 加载的计划基线的 `enabled` 属性。 |

#### 示例

```sql
DECLARE
  v_load_plans number;
BEGIN
  v_load_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
     sql_id => '529F6E6454EF579C7CC265D1F6131D70',
     plan_hash_value => 13388268709115914355);
END;
/

```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
