json解析导致cpu高但awr等待事件不显:因纯计算操作不触发i/o或锁等待,需查awr中db cpu绝对值、sql by cpu time及执行计划中的json evaluation step,并确保函数索引定义与sql调用字面完全一致。

直接查 JSON_VALUE 或 JSON_EXISTS 慢,AWR 里“Top Events”却风平浪静——这不是数据没毛病,而是瓶颈压根不在 I/O 或锁等待上,而在 CPU 解析开销里。
为什么“DB CPU”高但 Top 5 等待事件不报警
JSON 字段解析是纯计算型操作:Oracle 在运行时逐行提取、类型转换、路径匹配,全程不触发传统等待事件(比如 db file sequential read 或 enq: TX - row lock contention)。所以 AWR 的“Top 5 Timed Foreground Events”页面常显示负载“健康”,DB CPU 却悄悄占到 DB Time 的 70% 以上。
- 真正该盯的是报告开头的
DB Time和DB CPU绝对值,而不是占比;若DB CPU/Elapsed> 0.5(即每秒 CPU 耗时超 0.5 秒),且无其他明显等待,就该怀疑 JSON 解析 -
SQL ordered by CPU Time页面必须手动打开——别只看Elapsed Time或Executions,重点找CPU Time per Execution> 300ms 的 SQL - 常见漏网之鱼:某条含
JSON_VALUE(doc, '$.tags[0].name')的 SQL 执行次数少(比如每小时 12 次),但在 AWR 中被平均稀释,排不进 Top 10,但它单次就吃掉 1.8 秒 CPU
怎么从 SQL Statistics 定位 JSON 相关 SQL
在 SQL Statistics → SQL ordered by CPU Time 列表中,快速筛选出 JSON 相关语句,靠的不是肉眼扫函数名,而是组合条件:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 检查
SQL Text列是否包含JSON_VALUE、JSON_EXISTS、JSON_TABLE、IS JSON等关键字(大小写不敏感) - 确认该 SQL 的
Plan Hash Value是否稳定——如果同一sql_id对应多个不同 Plan Hash,说明绑定变量或统计信息导致计划漂移,JSON 解析可能时而走索引、时而全表扫 - 点进 SQL 详情页,看
Module和Action:应用层调用 JSON 接口的模块(如api.json.search)往往集中爆发,比后台批处理更值得优先干预
执行计划里必须验证的三个 JSON 关键点
AWR 报告本身不展示完整执行计划,但你能通过 Plan Hash Value 查 v$sql_plan 或用 DBMS_XPLAN.DISPLAY_AWR 提取。重点盯这三处:
- 是否存在
JSON EVALUATION STEP操作符——这是硬指标:只要出现,说明没走函数索引,纯运行时解析;哪怕加了索引,只要计划里没INDEX RANGE SCAN或INDEX UNIQUE SCAN,就是没命中 - 检查索引定义与 SQL 中的表达式是否严格一致:比如索引是
JSON_VALUE(doc, '$.status' RETURNING VARCHAR2(10)),但 SQL 写了UPPER(JSON_VALUE(doc, '$.status')),或比较时用了= 1(隐式转 NUMBER),都会导致索引失效 - 留意返回长度:若索引定义
RETURNING VARCHAR2(20),但实际 JSON 值长度为 25,Oracle 会自动退化为全表扫描+逐行解析,且不会报错,只在执行计划里藏一个FULL TABLE SCAN
ADDM 提示“Consider using function-based index”但没给 DDL 怎么办
ADDM 不会生成建索引语句,它只提示方向。你要自己反推:
- 回到目标 SQL 的详情页,复制完整的 JSON 表达式,包括路径、
RETURNING类型、错误处理子句(如ERROR ON ERROR) - 确认该表达式是
DETERMINISTIC的(JSON_VALUE默认是,但加了SYSDATE或序列就不行) - 建索引前先验证表达式是否可索引:
SELECT COUNT(*) FROM your_table WHERE JSON_VALUE(doc, '$.user.id' RETURNING NUMBER) IS NOT NULL;—— 若结果为 0,说明该路径下基本无有效值,建索引意义不大 - 建索引命令模板:
CREATE INDEX idx_json_user_id ON your_table (JSON_VALUE(doc, '$.user.id' RETURNING NUMBER));,注意不要加双引号,避免大小写敏感问题
最易忽略的一点:JSON 函数索引生效的前提,是 SQL 中的调用方式与索引定义**字面完全一致**——空格、换行、大小写、子句顺序,差一点,优化器就放弃使用。










