V$PGA_TARGET_ADVICE可信需满足:实例运行足够久、V$PGASTAT中缓存命中率长期<85%且over allocation count持续增长、ADVICE_STATUS为ENABLED、当前配置下预估命中率明显低于90%、ESTD_EXTRA_BYTES_RW非零且较大。
怎么看 V$PGA_TARGET_ADVICE 是否可信
它不是实时采样结果,而是基于实例启动以来 v$pgastat 累积的 pga 使用模式做的预测。所以刚重启的库,这个视图里数据基本是空的或不准——别急着调参。
判断是否可用,先查 V$PGASTAT 的 total PGA allocated 和 cache hit percentage:如果命中率长期低于 85%,且 over allocation count 在涨,说明当前 PGA_AGGREGATE_TARGET 确实偏小,V$PGA_TARGET_ADVICE 的建议才有参考价值。
- 执行
SELECT * FROM V$PGA_TARGET_ADVICE WHERE pga_target_factor = 1;,看当前配置下的预估命中率是否明显低于 90% - 检查
ESTD_EXTRA_BYTES_RW(预估额外物理读字节数):值越大,说明降配风险越高;若为 0,说明再降也影响不大 - 注意
ADVICE_STATUS字段:必须是ENABLED,否则顾问功能被禁用(可能因隐含参数或内存不足触发自动关闭)
怎么从 AWR 报告里快速定位排序区不足
AWR 报告中 “PGA Aggr Target Stats” 小节直接来自 V$PGA_TARGET_ADVICE,但真正暴露问题的,是 “SQL Statistics” → “SQL ordered by Reads” 或 “SQL ordered by Physical Read Bytes” 里的语句——它们往往正在大量使用磁盘临时段做排序/哈希连接。
- 关注 “Workarea Executions – Optimal / One-Pass / Multi-Pass” 这一行:如果
Multi-Pass占比 >5%,基本可断定排序区严重不足 - “PGA Cache Hit %” 低于 80% 是红色信号;低于 70% 通常伴随大量
direct path write temp和direct path read temp等待 - 别只盯平均值——点开 “Top SQL with Top Memory Usage” 查看单条 SQL 的
WORK_AREA_SIZE和实际使用的ACTUAL_MEM_USED,差几倍就说明该 SQL 被强制降级到磁盘了
为什么调大 PGA_AGGREGATE_TARGET 反而更慢
不是所有场景都适合加 PGA。OLTP 类业务如果盲目把 PGA_AGGREGATE_TARGET 设到 20G+,反而会挤占 SGA,导致 db cache hit ratio 下跌、逻辑读飙升,最终 CPU 更高、响应更卡。
- 确认业务类型:OLTP 建议
PGA_AGGREGATE_TARGET ≤ (total_mem × 0.8) × 0.2;DSS/报表类才考虑均分 - 检查
PGA_AGGREGATE_LIMIT:它默认是2GB或200% × PGA_AGGREGATE_TARGET,取大者。如果进程频繁报ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT,说明不是 target 小,而是 limit 卡死了 - 临时缓解可用
ALTER SYSTEM SET PGA_AGGREGATE_LIMIT=0 SCOPE=BOTH;,但这只是关掉熔断器,不解决根本问题
排查时最容易漏掉的两个点
一个是绑定变量缺失导致的硬解析风暴——每个不同字面量的 SQL 都单独分配 PGA 工作区,汇总看 V$PROCESS 里 PADDR 对应的 PGA_USED_MEM,你会发现几十个进程各自占了几百 MB,但没一个超限;另一个是 PL/SQL 数组批量操作,比如 BULK COLLECT INTO 没限制 LIMIT,一次拉几百万行进 PGA,瞬间打爆。
- 查异常 PGA 消耗会话:
SELECT pid, spid, program, pga_used_mem/1024/1024 mb FROM v$process ORDER BY pga_used_mem DESC FETCH FIRST 5 ROWS ONLY; - 查当前活跃大工作区:
SELECT sql_id, operation_type, policy, actual_mem_used/1024/1024 mb FROM v$sql_workarea_active WHERE actual_mem_used > 100*1024*1024; -
V$SQL_WORKAREA_HISTOGRAM里的LOW_OPTIMAL_SIZE和HIGH_OPTIMAL_SIZE范围,能告诉你大多数排序操作“本来想吃多少”,而不是“被迫吃了多少”
真正难的不是看懂数字,是把 V$PGA_TARGET_ADVICE 的百分比变化,和某次业务发布后多出的三条 SQL、两个未加 /*+ USE_HASH */ 的关联、或者 DBA 误删了 pga_aggregate_target 的历史快照,一一对应上。

















