---
title: OceanBase 数据库的 sql_id 和 plan_id 的稳定性介绍 -OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于OceanBase 数据库的 sql_id 和 plan_id 的稳定性介绍 相关的常见问题和使用技巧，帮助您快速解决OceanBase 数据库的 sql_id 和 plan_id 的稳定性介绍 的难题。
---
切换语言

- 简体中文
- English

划线反馈

# OceanBase 数据库的 sql_id 和 plan_id 的稳定性介绍

更新时间：2023-11-30 12:01

适用版本： V2.2.x 内容类型：TechNote  

OceanBase 数据库的 sql_id 和 plan_id 的稳定性很重要，因为它们是 SQL plan cache 的入口（包括 find plan detail, sql outline 绑定等)。本文主要介绍 sql_id 和 plan_id 的生成方式。

## 适用版本

OceanBase 数据库 V2.x 版本

## sql_id

sql_id 用于唯一确定一个查询语句，它是由查询语句经过快速参数化后得到的字符串的 MD5 值，返回 128 位的哈希值。sql_id 的长度为 CHAR(32)，形如 `ED570339F2C856BA96008A29EDF04C74`。

相同文本的 SQL 的 sql_id 总是相同的，可以通过以下脚本生成对应 SQL 的 sql_id。

```python
import hashlib
sql_text='SELECT * FROM t1 WHERE c2 = ?'
sql_id=hashlib.md5(sql_text.encode('utf-8')).hexdigest().upper()
print(sql_id)

```

## plan_id

plan_id 用于单个 OBServer 上唯一确定 plan_cache 中的一个plan，plan_id是一个递增的值，由 plan_cache 模块进行管理，每次新加入一个 plan 到 plan cache中时，都会为其分配一个 plan_id。plan_id 是 OBServer 启动后通过一个本地范围内的自增序列产生的值，OBServer 重启后，plan_id 会重置。plan_id 的长度为 `number(38)`，形如 `43213`。plan cache 是租户间隔离的，在一台 OBServer 中，plan_id 和 tenant_id 一起决定一个执行计划。

可以通过 `gv$plan_cache_plan_explain` 视图查询 plan。

根据上述得到的 `TENANT_ID`、`PLAN_ID`、`SVR_IP` 和 `SVR_PORT`，查询 `gv$plan_cache_plan_explain` 视图。

```unknow
obclient> SELECT * FROM gv$plan_cache_plan_explain WHERE tenant_id=1 AND plan_id=582518 and ip='11.1166.78.136' and port=2882;
+-----------+-----------------+------+---------+------------------+-----------------------+------+------+-------------------------------------------------------------------------------------------------------------------------------+
| TENANT_ID | IP              | PORT | PLAN_ID | OPERATOR         | NAME                  | ROWS | COST | PROPERTY                                                                                                                      |
+-----------+-----------------+------+---------+------------------+-----------------------+------+------+-------------------------------------------------------------------------------------------------------------------------------+
|         1 | xxx.xxx.xxx.xxx | 2882 |  582518 |  PHY_SORT        | NULL                  |  100 | 2418 | NULL                                                                                                                          |
|         1 | xxx.xxx.xxx.xxx | 2882 |  582518 |   PHY_TABLE_SCAN | __all_virtual_sysstat |  100 | 2000 | table_rows:100000, physical_range_rows:100, logical_range_rows:100, index_back_rows:0, output_rows:100, est_method:basic_stat |
+-----------+-----------------+------+---------+------------------+-----------------------+------+------+-------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.03 sec)

```

## 与 Oracle 数据库对比

- Oracle 数据库中的 sql_id 的生成方式是使用库缓冲存对象的名称计算 Hash MD5 , 得到 128 位哈希值。其中后 64 位为 sql_id，sql_id 的后32位为 **hash_value。**
 - 库缓冲通过 **hash_value** 定位。
 - 与 OceanBase 数据库的 sql_id 与 plan_id 生成方式不同，Oracle的 sql_id 与 SQL 的 hash_value 有关。
 - Oracle 数据库的 plan_hash_value 的作用类比于 OceanBase 数据库的 plan_id，虽然能绝大多数情况下识别一个 plan，但是也缺失了一些重要信息例如 mismatched predicates。
 - OceanBase 数据库的 plan_id 需要区分在不同 OBServer 启动生命期内的 Plan。因为OceanBase 数据库启动的前后，可能产生 sql_id、plan_id 相同的执行计划；但是由于分区迁移等情况，其实际的 Plan 结构是完全不同的。因此各种监控 console、巡检需要识别到这个不同的 Plan detail，而不是只靠 server_id+plan_id 进行查询。

Previous

[OceanBase 的 TRACE EVENT 是如何采集和实现的](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000284456)

Next

[NLJ/SPF batch rescan 问题汇总](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000816298) ![有帮助](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) 咨询热线
