AWR本身不直接暴露Child Cursor创建数量,但可通过Parse CPU to Parse Elapsd%<20%、Hard Parse占比>10%、SQL ordered by Parse Calls中Executions/Parse Calls≈1:1等指标定位硬解析、绑定变量不匹配及游标共享失效三大根因。

AWR 本身不直接暴露 Cursor Child 创建数量,但能定位导致 Child Cursor 泛滥的根本原因——必须查硬解析、绑定变量不匹配和游标共享失效这三类指标。
查 Parse CPU to Parse Elapsd % 和 Hard Parse 比例
硬解析是 Child Cursor 暴增的最常见源头。AWR 的 Instance Efficiency Percentages 区域里这两个值一高,基本就坐实了问题:
-
Parse CPU to Parse Elapsd %低于 20%:说明解析过程卡在 latch 等待上(比如latch: library cache),不是真在计算,而是争用严重 -
parse count (hard)/parse count (total)> 10%:硬解析占比过高,应用大概率没用绑定变量,或用了但字面量不一致(如:id和:ID大小写混用) - 对比正常时段报告:若该比例从 1% 突增至 15%,且
SQL ordered by Parse Calls里某几条 SQL 的 Parse Calls 暴涨,就是它们在反复生成新 Child
盯住 SQL Statistics → SQL ordered by Parse Calls
这里列出的是单位时间内解析调用最多的语句,不是执行最多的。Child Cursor 多的 SQL 往往在这里排前几位:
- 重点关注
Executions/Parse Calls接近 1:1 的 SQL——每次执行都重新解析,根本没复用游标 - 检查
SQL Text列:是否含字面量(WHERE status = 'ACTIVE')而非绑定变量(WHERE status = :b1) - 若看到同一逻辑 SQL 出现多个
SQL_ID,说明优化器因统计信息、NLS 设置等差异生成了不同子游标,得去查DBA_HIST_SQLSTAT确认CHILD_NUMBER分布
结合 v$sql_shared_cursor 查具体不共享原因
AWR 不存这个视图数据,但它是诊断 Child Cursor 分裂的最终依据。在问题时段连上库后立刻执行:
SELECT sql_id, child_number, bind_mismatch, optimizer_mode_mismatch, nls_mismatch, px_mismatch
FROM v$sql_shared_cursor
WHERE sql_id IN ('<code>your_sql_id</code>')
AND child_number > 0;
结果里哪一列是 Y,就对应哪类不匹配:
-
bind_mismatch = Y:绑定变量类型/长度不一致(如NUMBERvsVARCHAR2(10)) -
optimizer_mode_mismatch = Y:会话级OPTIMIZER_MODE不同(ALL_ROWSvsFIRST_ROWS) -
nls_mismatch = Y:NLS_SORT或NLS_COMP设置不同,常见于多语言应用未统一会话参数
别漏掉 DBA_HIST_SQLBIND 和 DBA_HIST_SQL_PLAN
迁移后容易忽略绑定变量实际传入值的变化。用 DBA_HIST_SQLBIND 查历史绑定值分布:
- 如果某绑定变量在 90% 的执行中传
NULL,10% 传具体值,Oracle 12c 可能因自适应游标共享(ACS)生成多个 Child 来适配不同值域 - 再用
DBMS_XPLAN.DISPLAY_AWR('<code>sql_id', NULL, 'ALLSTATS LAST') 对比各 Child 的执行计划:是否一个走索引、一个全表扫描?说明 ACS 起效但代价过高,需干预(如加 SQL Plan Baseline 或改写谓词)
真正难处理的不是 Child 数量本身,而是当 v$sql_shared_cursor 显示一堆 Y 却找不到统一诱因时——这时候往往要回溯迁移配置,比如 Oracle 兼容模式开关、cursor_sharing 参数是否被目标库覆盖、甚至 JDBC 驱动版本是否触发了隐式类型转换。


















