Oracle 性能问题排查
- 应用程序层面
- 代码逻辑问题:
检查应用程序的代码逻辑,看是否存在不合理的查询语句或者频繁的数据库操作。例如,是否有不必要的嵌套查询、循环中多次执行相同的 SQL 语句等。可以使用代码审查工具或者日志记录来定位问题代码。
- 连接池配置:
- 确认应用程序的数据库连接池配置是否合理。如果连接池的最大连接数设置过小,可能会导致应用程序在高并发情况下等待数据库连接,从而影响响应时间。可以调整连接池的参数,如最大连接数、最小连接数、连接超时时间等。
- 事务处理:
- 检查应用程序中的事务处理逻辑,确保事务的范围合理,避免长时间持有事务锁。过长的事务会导致其他事务等待,从而影响数据库的并发性能。
- 数据库服务器层面
- 监控数据库性能指标
- 会话信息:查看当前活动的会话,了解哪些用户或进程正在占用数据库资源。可以使用以下 SQL 语句查询:
SELECT sid, serial#, username, osuser, machine, program, status
FROM v$session
WHERE status = 'ACTIVE';
- 等待事件:分析数据库中的等待事件,找出导致性能瓶颈的原因。常见的等待事件包括 CPU 等待、磁盘 I/O 等待、网络等待等。可以使用以下 SQL 语句查询:
SELECT event, total_waits, time_waited, average_wait
FROM v$system_event
WHERE total_waits > 0
ORDER BY time_waited DESC;
- SQL 执行情况:查看执行时间较长的 SQL 语句,对这些语句进行优化。可以使用以下 SQL 语句查询:
SELECT *
FROM (
SELECT sql_text, elapsed_time, cpu_time, buffer_gets, disk_reads
FROM v$sql
ORDER BY elapsed_time DESC
)
WHERE ROWNUM <= 10;
- sql_text:此列存储的是实际执行的 SQL 语句的文本内容。通过查看 sql_text,你能够了解到数据库中正在执行哪些 SQL 语句,这对于性能分析和问题排查而言非常关键。例如,你可以依据这个内容判断是否存在复杂的查询或者低效的 SQL 语句。
- elapsed_time:它表示 SQL 语句从开始执行到执行结束所耗费的总时间,单位为微秒。这个时间包含了 SQL 语句在执行过程中所有的等待时间,像 CPU 时间、I/O 等待时间、锁等待时间等。elapsed_time 越长,表明该 SQL 语句的执行性能可能越差。
- cpu_time:指的是 SQL 语句在执行过程中实际占用 CPU 的时间,单位同样是微秒。这个指标可以帮助你了解 SQL 语句的 CPU 消耗情况。如果 cpu_time 很高,可能意味着该 SQL 语句存在复杂的计算逻辑或者算法效率低下。
- buffer_gets:代表 SQL 语句在执行过程中从数据库缓冲区(Buffer Cache)里获取数据块的次数。数据库缓冲区是一块内存区域,用于缓存经常访问的数据块。buffer_gets 次数越多,说明 SQL 语句需要访问的数据量越大,或者数据的缓存命中率较低。
- disk_reads:表示 SQL 语句在执行过程中从磁盘读取数据块的次数。由于磁盘 I/O 操作的速度远低于内存操作,disk_reads 次数过多通常会导致 SQL 语句执行性能下降。这个指标可以帮助你判断 SQL 语句是否存在大量的磁盘 I/O 操作。
b. 分析数据库配置
- 内存参数:确保 SGA(System Global Area)和 PGA(Program Global Area)的大小设置合理,以满足数据库的运行需求。可以通过以下 SQL 语句查询当前的内存参数:
SELECT name, value, description
FROM v$parameter
WHERE name LIKE '%sga%';
SELECT name, value, description
FROM v$parameter
WHERE name LIKE '%pga%';
- 查询管理模式:
SELECT name, value
FROM v$parameter
WHERE name = 'sga_target';
0= 手动模式
- 查看 SGA 各组件当前大小
SELECT name, value
FROM v$parameter
WHERE name LIKE '%sga%' AND value IS NOT NULL;
- 调整 SGA 组件大小示例
-- 若要调整数据缓冲区高速缓存的大小为 2GB,可使用如下语句
ALTER SYSTEM SET db_cache_size = 2G SCOPE = SPFILE;
在修改参数之后,需要重启数据库让修改生效:
c. 实时监控会话数
- 查询当前活跃会话数和历史峰值,判断是否超出当前参数限制:
-- 当前活跃会话数
SELECT COUNT(*) FROM v$session WHERE status = 'ACTIVE';
-- 历史会话数高峰(需依赖 AWR 报告)
SELECT MAX(session_count) FROM dba_hist_snapshot;
- 检查进程使用情况
确认进程数是否接近 PROCESSES 上限:
SELECT COUNT(*) FROM v$process;
- PROCESSES 参数
- 作用:
- PROCESSES 定义了 Oracle 数据库实例可以同时运行的最大进程数,包括后台进程(如 DBWR、LGWR 等)和用户进程。默认值:
- 通常由 Oracle 自动设置(例如 150),但实际应根据系统负载调整。计算公式:
SESSIONS 的默认值 = PROCESSES × 1.1 + 5(例如,PROCESSES=150 时,SESSIONS=170)。
- SESSIONS 参数
- 作用:
- SESSIONS 控制数据库可以同时打开的最大会话数,每个用户连接(如应用程序或客户端工具)对应一个会话。默认值:
- 由 PROCESSES 自动推导,通常满足大多数场景需求。调整场景:
当并发用户数超过默认值时,需手动增大 SESSIONS。例如,若 SESSIONS=170 但实际需要 300 个并发会话,需调整 PROCESSES 和 SESSIONS。
- 网络层面
- 存储层面
操作作日志异常
时间点 |
running time |
ms % Task name |
2025-03-14 09:18:31 |
(millis) = 44025 |
34996 079% xxxxxxxxx 07060 016% xxxxxxxxx |
2025-03-14 09:18:58 |
(millis) = 43200 |
34144 079% xxxxxxxxx |