db cpu占比高但awr无明显高消耗sql,大概率是硬解析失控、后台任务密集或索引失效引发隐式全表扫描;需查parse cpu to parse elapsd %<20%、硬解析超500次/小时、latch争用及mmon/mmnl空转等隐蔽根源。

DB CPU占比高但AWR里找不到明显高消耗SQL,大概率不是SQL执行问题,而是硬解析失控、后台任务密集或索引失效引发的隐式全表扫描——这些行为不体现在Top SQL列表中,却把CPU耗在“看不见”的地方。
查Parse CPU to Parse Elapsd %和硬解析次数
硬解析泛滥时,CPU主要花在语法校验、权限检查、计划生成上,而不是SQL执行本身,所以Top SQL里看不到它:
-
Parse CPU to Parse Elapsd %低于20%,说明解析阶段CPU效率极低 -
parse count (hard)每小时超500次,基本可判定为绑定变量缺失 -
SELECT sql_id, parse_calls, executions FROM dba_hist_sqlstat WHERE snap_id IN (xxx, yyy) AND parse_calls > executions * 0.9—— 这类SQL就是硬解析主力
盯住latch: shared pool和library cache等待事件
这两个等待排进Top 5,就说明CPU正被大量争用闩锁拖住,典型表现是会话状态为ON CPU但没SQL_ID,或者sql_id为空:
- 常见诱因:
NLS_LANGUAGE或NLS_TERRITORY在不同会话间不一致,导致相同SQL被当成多条语句反复硬解析 - 确认方式:
SELECT DISTINCT nls_language, nls_territory FROM v$session - 共享池过小也会加剧争用,但先查参数再调大小,别一上来就
ALTER SYSTEM SET shared_pool_size
检查MMON/MMNL后台进程是否在“空转”
Oracle 11g默认开启自动统计收集和ASH刷新,ora_mmon_*和ora_mmnl_*可能在后台持续高负载运行:
- 查它们是否真在
ON CPU:SELECT program, event, p1text, p1 FROM v$session WHERE program LIKE 'ora_mmon%' AND state = 'ON CPU' - 若
STATISTICS_LEVEL = 'TYPICAL'(默认),且刚重启或AWR保留天数过长(如60天),MMON扫描历史数据量暴增 - 临时缓解:
EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(retention => 7*1440)缩短保留期
翻Segments by Logical Reads找“隐形凶手”
一张索引失效的表,会让所有DML和查询都退化为全表扫描,逻辑读飙升,但单条SQL看起来都很“正常”:
- AWR报告中
Segments by Logical Reads排第一的表,立刻查其索引状态:SELECT index_name, status FROM dba_indexes WHERE table_name = 'XXX' AND status != 'VALID' - 分区表迁移后索引变
UNUSABLE,是高频陷阱 - 配合
Segment Statistics → Index Usage看该索引是否长期未被使用,但又突然出现在高逻辑读列表里
真正难缠的CPU问题,往往藏在AWR报告的边角:不在Top SQL里,在Time Model Statistics的parse time elapsed里,在latch等待里,在Segments统计里——盯着单一视图容易漏掉交叉线索。











