---
title: "计划缓存概述 - OceanBase 数据库 V4.3.5 | OceanBase 文档中心"
description: 计划缓存概述 OceanBase 数据库通过复杂的改写规则和计划生成算法提供了强大的优化能力，但这也导致计划生成耗时增加。例如，在极端 TP 场景中，一条主键单点查询的计划生成时间可能达 1ms，而实际执行仅需 0.5ms。若每条 SQL 都重新生成计划，耗时将主要集中在计划生成阶段。为此，OceanBase 引入 …
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

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

# 计划缓存概述

更新时间：2026-04-07 20:57:20

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.3.5/zh-CN/600.manage/900.performance-tuning/400.sql-tuning/200.execution-plan-optimization/200.plan-management/100.plan-cache-overview.md)  

OceanBase 数据库通过复杂的改写规则和计划生成算法提供了强大的优化能力，但这也导致计划生成耗时增加。例如，在极端 TP 场景中，一条主键单点查询的计划生成时间可能达 1ms，而实际执行仅需 0.5ms。若每条 SQL 都重新生成计划，耗时将主要集中在计划生成阶段。为此，OceanBase 引入 **计划缓存（Plan Cache）** 机制，使相同 SQL 共享执行计划，显著降低响应时间。

## 典型场景

在 HTAP 业务中，若某 SQL 的执行时间远超计划生成时间（例如执行时间 10ms，计划生成时间 1ms），且 `执行时间/生成时间 = 10`（超过默认阈值 5），则连续触发 5 次后，系统会自动关闭该 SQL 的计划缓存，以优化其执行性能。

## 计划缓存机制

### 核心流程

1. **SQL 参数化**：

      - 当 OceanBase 数据库收到一条 SQL 请求后，首先会通过通过 `fast parser` 模块将 SQL 文本中的常量参数替换为通配符 `?`。
      - 示例：`SELECT * FROM t1 WHERE c1 = 1` 替换为 `SELECT * FROM t1 WHERE c1 = ?`。
 2. **缓存命中检查**：

      - 查找参数化后的 SQL 是否已有缓存计划。
      - 若命中缓存：直接执行已有计划。
      - 若未命中：生成新计划并存入缓存。
 3. **性能优势**：

      - 从缓存获取计划的耗时通常比重新生成 **低一个数量级**（例如从 1ms 缩短至 0.1ms）。

![计划缓存](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer-enterprise/V4.2.1/manage/plan-manage.png)

## 自适应计划缓存

在 HTAP 混合负载场景中：

- **TP 场景**：需开启计划缓存以减少重复生成计划的耗时。 默认开启。
 - **AP 场景**：关闭计划缓存可提升性能（因计划生成更优但耗时）。
 - **HTAP 混合负载的业务场景**：关闭 Plan Cache 虽然可以让偏 AP 的 SQL 获得更好的性能，但是也会让偏 TP 的 SQL 受到极大的影响。

**OceanBase V4.3.5 BP2 版本** 新增 **自适应计划缓存**，根据 SQL 特性动态决定是否启用计划缓存，平衡两类场景的性能。

### 关键配置项

OceanBase 数据库在 V4.3.5 BP2 版本新增自适应计划缓存相关配置项：

- `enable_adaptive_plan_cache`：租户级配置项，用于控制租户是否开启计划缓存自适应的能力。详细介绍信息，参见 [enable_adaptive_plan_cache](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002974745)。
 - `_pc_adaptive_min_exec_time_threshold`：租户级隐藏配置项，该配置项用于控制启用自适应计划缓存的最小执行时间阈值，即在自适应计划缓存功能开启的情况下，执行时间超过该阈值的 SQL 才开启自适应计划缓存。属性说明如下：

  | **属性** | **描述** |
  | --- | --- |
  | 参数类型 | TIME |
  | 默认值 | 1s |
  | 取值范围 | [0, +∞] |
  | 是否可修改 | 是，支持通过 `ALTER SYSTEM SET` 语句修改该配置项的值。例如：`ALTER SYSTEM SET _pc_adaptive_min_exec_time_threshold = '2s';`。   #### 说明    Oracle 模式下，在语法上隐藏配置项需加双引号。 |
  | 是否重启 OBServer 节点生效 | 否，设置后立即生效。 |
 - `_pc_adaptive_effectiveness_ratio_threshold`：租户级隐藏配置项，该配置项用于控制启用自适应计划缓存的最小比率阈值，即在自适应计划缓存功能开启的情况下，计划执行时间/计划生成时间 大于等于该阈值才开启自适应计划缓存。属性说明如下：

  | **属性** | **描述** |
  | --- | --- |
  | 参数类型 | INT |
  | 默认值 | 5 |
  | 取值范围 | [0, +∞] |
  | 是否可修改 | 是，支持通过 `ALTER SYSTEM SET` 语句修改该配置项的值。例如：`ALTER SYSTEM SET _pc_adaptive_effectiveness_ratio_threshold = 6;`。   #### 说明    Oracle 模式下，在语法上隐藏配置项需加双引号。 |
  | 是否重启 OBServer 节点生效 | 否，设置后立即生效。 |
 - `_force_enable_plan_tracing`：租户级隐藏配置项，该配置项用于控制在禁用计划缓存时是否启用计划跟踪。属性说明如下：

  | **属性** | **描述** |
  | --- | --- |
  | 参数类型 | BOOL |
  | 默认值 | TRUE，表示在禁用计划缓存时启用计划跟踪。 |
  | 取值范围 | - TRUE   - FALSE |
  | 是否可修改 | 是，支持通过 `ALTER SYSTEM SET` 语句修改该配置项的值。例如：`ALTER SYSTEM SET _force_enable_plan_tracing = FALSE;`。   #### 说明    Oracle 模式下，在语法上隐藏配置项需加双引号。 |
  | 是否重启 OBServer 节点生效 | 否，设置后立即生效。 |

### 自适应关闭条件

当自适应功能开启时，若一条 SQL 满足以下 **所有条件**，系统会 **关闭其计划缓存**：

1. **执行时间阈值**：
      - SQL 执行时间 ≥ `_pc_adaptive_min_exec_time_threshold`（默认 1 秒）。
 2. **效率比率阈值**：
      - `执行时间 / 计划生成时间 ≥ _pc_adaptive_effectiveness_ratio_threshold`（默认 5）。
 3. **连续触发次数**：
      - 连续 5 次执行均满足上述条件。

## 查询和管理缓存的执行计划

OceanBase 数据库提供了以下两个系统视图，用于查询和管理缓存的执行计划：

- `GV$OB_PLAN_CACHE_PLAN_STAT`：记录每个执行计划在计划缓存中的实际计划形态，通过指定（ip、port、 tenant_id、plan_id）的四元组，可以查到一个特定计划的树型计划形态。通过这个视图，我们可以找到 server 中消耗 CPU 多的 SQL 进行调优，从而优化数据库的性能。
 - `GV$OB_PLAN_CACHE_PLAN_EXPLAIN`：视图记录每个执行计划在计划缓存中的实际计划形态，通过指定（ip、port、 tenant_id、plan_id）的四元组，可以查到一个特定计划的树型计划形态。

### 查询计划的示例

以下 SQL 展示如何通过 `GV$OB_PLAN_CACHE_PLAN_EXPLAIN` 获取特定计划的形态：

```sql
SELECT plan_line_id, operator, name, rows, cost  
FROM oceanbase.gv$ob_plan_cache_plan_explain  
WHERE svr_ip = 'xx.xx.xx.xx'  
  AND svr_port = 30042  
  AND tenant_id = 1001  
  AND plan_id = 248;  

```

**执行结果**：

```shell
+--------------+------------------------+--------------+---------+----------+  
| plan_line_id | operator               | name         |  rows   |  cost    |  
+--------------+------------------------+--------------+---------+----------+  
|            0 | PHY_SORT               | NULL         |  6      |  16522   |  
|            1 |  PHY_HASH_GROUP_BY     | NULL         |  6      |  16506   |  
|            2 |   PHY_TABLE_SCAN       | lineitem     |  11473  |   6597   |  
+--------------+------------------------+--------------+---------+----------+  

```

可以看到这个结果与在 OceanBase 数据库直接执行 explain 的结果是非常相似的。需要注意的是这里查出的计划是使用对应 SQL 第一次执行的参数生成的，可能出现一条 SQL 执行 explain 计划的结果与 `GV$OB_PLAN_CACHE_PLAN_EXPLAIN` 中查出的结果不一致的情况。这时我们就可以考虑是不是遇到了计划缓存的 bad case 了，是否需要通过计划绑定来固定一个稳定的计划。

## 相关文档

查询缓存的执行计划视图相关文档如下：

- [GV$OB_PLAN_CACHE_PLAN_STAT（sys 租户）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015014)
 - [GV$OB_PLAN_CACHE_PLAN_STAT（MySQL 模式）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015108)
 - [GV$OB_PLAN_CACHE_PLAN_STAT（Oracle 模式）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002014123)
 - [GV$OB_PLAN_CACHE_PLAN_EXPLAIN（sys 租户）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002014918)
 - [GV$OB_PLAN_CACHE_PLAN_EXPLAIN（MySQL 模式）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015155)
 - [GV$OB_PLAN_CACHE_PLAN_EXPLAIN（Oracle 模式）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002014105)

 上一篇 下一篇 ![有帮助](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) 咨询热线
