Oracle 数据库 CPU 高排查

Oracle 数据库 CPU 高排查

适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

CPU 高是常见性能问题[1]:

原因

  • 慢 SQL
  • 高解析
  • 排序
  • 后台进程

2. 排查步骤

2.1 OS 层

# CPU 使用
top
ps -e -o pcpu,pid,cmd --sort=-pcpu | head -20

# Oracle 进程
ps -e -o pcpu,pid,cmd --sort=-pcpu | grep ora_

2.2 数据库层

-- 1. 高 CPU 会话
SELECT 
  s.sid,
  s.serial#,
  s.username,
  s.program,
  s.sql_id,
  s.event,
  s.module
FROM v$session s, v$process p
WHERE s.paddr = p.addr
  AND s.status = 'ACTIVE'
ORDER BY p.spid;

-- 2. CPU 使用统计
SELECT 
  s.sid,
  n.name,
  s.value / 100 AS cpu_sec
FROM v$sesstat s, v$statname n, v$session ss
WHERE s.statistic# = n.statistic#
  AND s.sid = ss.sid
  AND n.name = 'CPU used by this session'
ORDER BY s.value DESC;

2.3 Top SQL

-- CPU 高 SQL
SELECT sql_id, cpu_time / 1000000 AS cpu_sec, executions
FROM v$sql
ORDER BY cpu_time DESC
FETCH FIRST 10 ROWS ONLY;

3. 常见 CPU 高原因

3.1 慢 SQL

-- 全表扫描
SELECT * FROM big_table WHERE ...;

-- 优化:加索引

3.2 高解析

-- 硬解析多
SELECT name, value FROM v$sysstat 
WHERE name IN ('parse count (hard)', 'parse count (total)');

-- 优化:绑定变量

3.3 排序

-- 大排序
SELECT * FROM big_table ORDER BY ...;

-- 优化:索引、PGA

3.4 锁

-- 锁等待导致 spin
SELECT event, COUNT(*) FROM v$session 
WHERE event LIKE 'latch%' GROUP BY event;

3.5 后台进程

SELECT 
  program,
  COUNT(*) 
FROM v$process 
GROUP BY program;

4. ASH 分析

-- 1. CPU 高时段
SELECT 
  TO_CHAR(sample_time, 'HH24:MI') AS t,
  COUNT(CASE WHEN session_state = 'ON CPU' THEN 1 END) AS on_cpu,
  COUNT(*) AS total
FROM v$active_session_history
WHERE sample_time > SYSDATE - 1/24
GROUP BY TO_CHAR(sample_time, 'HH24:MI')
ORDER BY 1;

-- 2. Top CPU SQL
SELECT 
  sql_id,
  COUNT(CASE WHEN session_state = 'ON CPU' THEN 1 END) AS cpu_samples
FROM v$active_session_history
WHERE sample_time > SYSDATE - 1/24
GROUP BY sql_id
ORDER BY cpu_samples DESC
FETCH FIRST 10 ROWS ONLY;

5. AWR 分析

5.1 Top 5 Events

CPU 时间占比高
解析多
排序多

5.2 SQL by CPU

Top SQL by CPU Time

5.3 Instance Efficiency

Parse CPU to Execute Ratio
Soft Parse %

6. 优化策略

6.1 SQL 优化

-- 1. 加索引
-- 2. 重写 SQL
-- 3. HINT
-- 4. SQL Profile

6.2 绑定变量

-- 1. 应用层
EXECUTE IMMEDIATE 'SELECT ... WHERE id = :1' USING v_id;

-- 2. CURSOR_SHARING
ALTER SYSTEM SET cursor_sharing = FORCE;

6.3 增大 PGA

ALTER SYSTEM SET pga_aggregate_target = 8G;

6.4 增大 Shared Pool

ALTER SYSTEM SET shared_pool_size = 4G;

6.5 并行优化

-- 限制并行度
ALTER SYSTEM SET parallel_max_servers = 16;

7. 实战案例

7.1 案例:CPU 100%

1. top 找进程
2. ASH 找 SQL
3. SQL 执行计划:全表
4. 加索引
5. CPU 下降

7.2 案例:解析高

1. AWR: hard parse 50%
2. 应用无绑定变量
3. 改造绑定变量
4. 解析下降

7.3 案例:锁 spin

1. Top Event: latch: shared pool
2. SQL 多
3. 绑定变量
4. Shared Pool
5. latch 下降

8. 监控

8.1 CPU 监控

SELECT 
  metric_name, 
  value
FROM v$sysmetric
WHERE metric_name LIKE 'CPU%'
ORDER BY begin_time DESC;

8.2 告警

CPU > 80% 持续 5 分钟
CPU > 90% 持续 1 分钟

9. 常见坑与排错

9.1 误判

- 后台进程 CPU
- 系统进程
- 非 Oracle 进程

9.2 临时高

- 定时任务
- 大查询
- 等待结束

9.3 持续高

- 慢 SQL
- 资源不足
- 配置不当

10. 最佳实践

  1. OS + DB 双层:定位
  2. ASH 时段:精准
  3. Top SQL:根因
  4. 索引优化:常用
  5. 绑定变量:解析
  6. PGA 调优:排序
  7. Shared Pool:解析
  8. 监控告警:及时
  9. 基线对比:异常
  10. 持续优化:循环

11. 参考资料

[1] Oracle Database Performance Tuning Guide 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/tgdba/