基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
如何排查常量约束导致的参数不匹配,计划不命中的问题
更新时间:2026-05-14 07:41
在数据库运行过程中,SQL 执行计划无法命中是一个常见的性能问题,往往会导致大量的硬解析,从而显著降低系统的执行效率。造成计划无法共享的原因多种多样,本文将重点分析由于常量约束不匹配而导致计划未命中的问题,并提供相应的排查思路。
详细说明
简化测试用例如下: 多次执行 SQL 查询, count 不同的常量。
OceanBase(SYS@SYS)> select /*+ ml_test */ count(1) from dual;
+----------+
| COUNT(1) |
+----------+
| 1 |
+----------+
1 row in set (0.004 sec)
OceanBase(SYS@SYS)> select /*+ ml_test */ count(2) from dual;
+----------+
| COUNT(2) |
+----------+
| 1 |
+----------+
1 row in set (0.004 sec)
OceanBase(SYS@SYS)> select /*+ ml_test */ count(3) from dual;
+----------+
| COUNT(3) |
+----------+
| 1 |
+----------+
1 row in set (0.004 sec)
OceanBase(SYS@SYS)> select /*+ ml_test */ count(4) from dual;
+----------+
| COUNT(4) |
+----------+
| 1 |
+----------+
1 row in set (0.003 sec)
查看执行每次都需要硬解析,没有命中计划。
OceanBase(root@oceanbase)> select query_sql, is_hit_plan from oceanbase.GV$OB_SQL_AUDIT where query_sql like 'select /*+ ml_test / count%from dual%';
+--------------------------------------------+-------------+
| query_sql | is_hit_plan |
+--------------------------------------------+-------------+
| select /+ ml_test / count(1) from dual | 0 |
| select /+ ml_test / count(2) from dual | 0 |
| select /+ ml_test / count(3) from dual | 0 |
| select /+ ml_test */ count(4) from dual | 0 |
+--------------------------------------------+-------------+
explain extended 计划,可以看到,计划中有常量约束。

根据执行不命中计划的 trace_id 在 OBServer 日志中进行过滤,可以看到添加计划之后,检测到存在相同的 pcv,但是进行约束匹配(match_constraints)时候,返回 not matched const param,这里不匹配的原因是原来 pcv 中的值是 number 类型,数字 7,但是当前传入的是 number 类型,数字 8。 这里匹配过于严格,不仅要求精度/类型一样, 还要求传入的值一样(此问题在绑定 outline 后无法命中 plan cache 种修复)。 日志中可以看到,当常量约束不匹配时,生成了新的计划。

其他导致常量约束不能命中的可能原因有:
字符集相关。
数值精度不一致。
参数类型不一致。
字符拼接导致不能命中。
当前常量约束主要进行如下检查:
检查当前参数是否与缓存的常量参数约束匹配:验证约束的完整性,逐个检查参数约束的参数类型,参数值。
检查是否存在生成列约束,并逐个检查参数以及约束的完整性。
检查参数间的相等关系约束和不同数据类型的比较。
当遇到其他原因导致的常量约束不匹配的情况,需要通过 trace 日志和原始 SQL,计划等,进一步分析不匹配的原因。
适用版本
OceanBase 数据库 V4.x 版本。