🔗 接上一篇《Oracle锁问题与阻塞分析》,今天我们深入数据库的"神经系统"------性能瓶颈定位,解决慢查询和系统卡顿问题。
你是否遇到过:
- SQL执行突然变慢?
- 系统整体响应延迟?
- I/O等待时间过长?
这些问题,往往源于性能瓶颈。今天,我就带你从SQL、内存、I/O三个维度,系统性定位性能问题。
🧠 性能瓶颈三大来源
| 来源 | 占比 | 诊断工具 |
|---|---|---|
| SQL问题 | ~60% | SQL Monitor, AWR |
| 内存不足 | ~25% | vsgastat ,vpgastat |
| I/O瓶颈 | ~15% | v$system_event, AWR |
✅ 定位原则:先看全局,再聚焦个体。
1️⃣ SQL性能分析
✅ 高负载SQL识别
sql
-- 按CPU时间排序的SQL
SELECT
sql_id,
sql_text,
executions,
elapsed_time / executions / 1000 AS avg_etime_ms,
cpu_time / executions / 1000 AS avg_cpu_ms,
buffer_gets / executions AS avg_lio
FROM
v$sql
WHERE
executions > 0
AND elapsed_time > 0
ORDER BY
cpu_time DESC
FETCH FIRST 10 ROWS ONLY;
✅ 关键指标:
avg_etime_ms:平均执行时间avg_cpu_ms:平均CPU时间avg_lio:平均逻辑I/O
✅ SQL执行计划查看
sql
-- 查看特定SQL的执行计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', NULL, 'ALLSTATS LAST'));
🔍 关注点:
- 是否有全表扫描(TABLE ACCESS FULL)
- 是否有嵌套循环(NESTED LOOPS)导致性能下降
- 实际行数 vs 预估行数差异
2️⃣ 内存使用分析
✅ SGA内存分布
sql
-- SGA各组件大小
SELECT
pool,
name,
ROUND(bytes/1024/1024, 2) AS size_mb
FROM
v$sgastat
WHERE
name IN ('free memory')
AND pool IN ('DEFAULT buffer cache', 'shared pool')
ORDER BY
pool, bytes DESC;
✅ 解读:
DEFAULT buffer cache:数据缓存shared pool:SQL和PL/SQL缓存free memory过少 → 内存压力
✅ PGA内存监控
sql
-- PGA内存使用
SELECT
name,
ROUND(value/1024/1024, 2) AS mb
FROM
v$pgastat
WHERE
name IN (
'total PGA allocated',
'total PGA used',
'maximum PGA allocated',
'over allocation count'
);
🚨 警报:
over allocation count > 0→ PGA过度分配,使用了临时表空间total PGA used接近pga_aggregate_target→ 需扩容
3️⃣ I/O性能深度检测
✅ I/O等待事件分析
sql
-- User I/O 等待事件
SELECT
event,
total_waits,
time_waited * 10 AS time_waited_ms,
average_wait * 10 AS avg_wait_ms
FROM
v$system_event
WHERE
wait_class = 'User I/O'
ORDER BY
time_waited DESC;
✅ 健康标准:
- 平均等待 < 20ms:良好
- 20-50ms:关注
- 50ms:需优化
✅ 物理I/O热点表
sql
-- 高I/O的表段
SELECT
owner,
segment_name AS "Table",
ROUND(SUM(bytes) / 1024 / 1024, 2) AS "Size (MB)"
FROM
dba_segments
WHERE
segment_type = 'TABLE'
AND owner = 'YOUR_SCHEMA'
GROUP BY
owner, segment_name
ORDER BY
SUM(bytes) DESC
FETCH FIRST 10 ROWS ONLY;
🔍 关联分析:
大表 + 高I/O等待 → 可能需要分区或索引优化。
4️⃣ 表膨胀与空间分析
sql
-- 表大小分析
SELECT
owner,
segment_name AS "Table",
ROUND(SUM(bytes) / 1024 / 1024, 2) AS "Size (MB)"
FROM
dba_segments
WHERE
segment_type = 'TABLE'
AND segment_name IN ('TABLE1', 'TABLE2')
AND OWNER = 'SCHEMA_NAME'
GROUP BY
owner, segment_name
ORDER BY
SUM(bytes) DESC;
✅ 解读:
- 结合业务判断表大小是否合理
- 异常增长 → 检查是否有数据积压或归档问题
📣 总结
性能瓶颈定位三板斧:
- 📊 用
v$system_event看等待事件 - 🔍 用
v$sql找高负载SQL - 💾 用
v$sgastat/v$pgastat查内存使用
🔗 下期预告:
下一篇《Oracle表空间与对象管理》,我们将深入表空间、段、分区的管理与优化。
📌 点赞 + 收藏,掌握性能分析核心技能!
👉 让你的SQL飞起来!