oracle数据库cpu飙高需结合awr报告综合判断:先看db cpu占db time比例是否超40%、aas是否持续超核数,再聚焦sql的cpu per exec与执行频次,排查硬解析、执行计划突变及后台任务。

Oracle数据库CPU飙高,不能只看操作系统top里oracle进程占了90%就动手杀会话——AWR报告里DB CPU占DB Time比重、Average Active Sessions是否超核数、以及SQL ordered by CPU Time里每条SQL的CPU per Exec值,才是判断真瓶颈的关键。
先确认DB CPU是否真高,别被OS层假象带偏
操作系统看到oracle进程CPU使用率85%,不代表数据库内部真在满负荷计算。必须进AWR报告看Time Model Statistics页:
-
DB CPU占DB Time比例低于40%?那大概率不是SQL执行问题,而是latch: shared pool或library cache争用导致CPU耗在解析等待上 -
Average Active Sessions(AAS)=DB Time / Elapsed Time,若12核机器AAS持续>15,才说明并发活跃度真压垮了CPU资源 -
DB CPU数值是累计值:报告里显示3600秒,意味着该时段平均每秒消耗了300秒CPU时间(即25核等效满载),远超物理核数
查SQL ordered by CPU Time时,重点看CPU per Exec而非总CPU
AWR默认按累计CPU时间排序,但真正拖垮系统的往往是那些单次执行就吃掉10秒CPU、且每秒执行多次的语句。注意过滤:
- 跳过
EXECUTIONS = 0但CPU_TIME_SEC > 0的SQL——这类是游标异常终止或统计未刷新的干扰项 - 重点关注
CPU per Exec > 5且Executions per Sec > 0.1的SQL,它们才是稳定输出CPU压力的“定时炸弹” - 同一
sql_id在不同快照里CPU per Exec突增3倍以上?立刻用DBMS_XPLAN.DISPLAY_AWR('<sql_id>')</sql_id>查执行计划,确认是否出现FULL TABLE SCAN或NESTED LOOPS放大
硬解析失控时,CPU高但Top SQL不显眼
当Parse CPU to Parse Elapsd %低于20%,或parse count (hard)每小时超过500次,说明大量CPU耗在语法校验、权限检查、计划生成上,而不是SQL执行本身:
- 检查应用是否漏写绑定变量——
sql_text里带字面量(如WHERE id = 123)而非WHERE id = :b1 - 确认NLS参数是否漂移:
v$session里nls_language、nls_territory不一致会导致相同SQL被当成不同语句硬解析 - 查
dba_hist_sqlstat中parse_calls ≈ executions的SQL,这类就是硬解析失控的典型
Plan_hash_value突变比SQL本身更危险
AWR报告只列Top 30 SQL,且不标记执行计划是否变化。很多CPU飙升源于plan_hash_value从12345变成67890,但报告里根本看不出:
- 手动查
DBA_HIST_SQLSTAT:SELECT sql_id, plan_hash_value, executions, ROUND(elapsed_time / NULLIF(executions, 0) / 1000000, 2) AS ela_sec_per_exec FROM dba_hist_sqlstat WHERE snap_id BETWEEN &begin_snap AND &end_snap ORDER BY ela_sec_per_exec DESC - 发现同一
sql_id在相邻快照中plan_hash_value不同?立刻用DBA_HIST_SQL_PLAN对比两套计划,重点看access_predicates和filter_predicates是否丢失谓词下推 - 计划突变常由统计信息陈旧、直方图失效或SQL Profile误启用引发,不能只盯着SQL文本改写
最易被忽略的是:CPU飙高未必来自前台SQL,而可能来自物化视图定时刷新、JOB任务集中触发,或PL/SQL过程里隐式游标循环——这些在SQL ordered by CPU Time里根本不显形,得靠ASH按session_state = 'ON CPU'聚合后反查plsql_entry字段才能定位。











