Oracle PGA 优化

PGA(程序全局区)是 Oracle 数据库中每个服务器进程私有的内存区域,专门用于处理 SQL 执行过程中的排序、哈希连接、位图合并等私有操作。PGA 优化的核心是让尽可能多的内存密集型操作在内存中完成,避免频繁读写临时表空间,从而将 SQL 执行速度提升 10-100 倍。

一、PGA 基础

1.1、什么是 PGA 优化

PGA 优化是通过调整 PGA 管理模式、分配总内存大小、优化 SQL 执行逻辑和限制进程资源使用,实现以下三个核心目标:

  • 提高 Optimal 执行比例:让 90% 以上的内存操作在内存中完成
  • 避免 Multi-pass 执行:完全杜绝多次读写临时表空间的情况
  • 防止内存溢出:限制单个进程的 PGA 使用,避免数据库 OOM 崩溃

1.2、PGA 内存架构

PGA(每个进程私有)

  • 工作区(Work Area):SQL执行的核心内存
    • 排序区(Sort Area):ORDER BY/GROUP BY/DISTINCT/UNION
    • 哈希连接区(Hash Area):大表哈希连接
    • 位图合并区(Bitmap Merge Area):位图索引合并
    • 聚合区(Aggregation Area):SUM/AVG/COUNT等聚合函数
  • 会话内存(Session Memory)
    • 游标状态
    • 会话变量
    • 堆栈空间

1.3、PGA vs SGA 核心区别

对比维度 PGA SGA
共享性 每个进程私有 所有进程共享
用途 排序、哈希连接、聚合 缓存数据块、SQL 执行计划
大小 随进程动态变化 相对固定
优化重点 减少磁盘排序和哈希 提高缓存命中率

1.4、PGA 优化核心原则

  • 自动管理优先:生产环境必须使用自动 PGA 管理,禁止手动管理
  • 按需分配:OLAP 系统侧重 PGA(占总内存 30-40%),OLTP 系统侧重 SGA(占总内存 60-70%)
  • 上限控制:必须设置 PGA_AGGREGATE_LIMIT,防止单个进程耗尽所有内存
  • SQL 优化优先:优化 SQL 减少排序和哈希连接,比单纯增加内存更有效

二、PGA 管理模式

1、自动 PGA 管理

Oracle 9i 及以上版本支持自动 PGA 管理,这是生产环境的推荐方式。

启用自动PGA管理:

ALTER SYSTEM SET WORKAREA_SIZE_POLICY=AUTO SCOPE=BOTH;

设置PGA总大小:

ALTER SYSTEM SET PGA_AGGREGATE_TARGET=4G SCOPE=BOTH;

设置PGA最大限制(防止单个进程消耗过多内存):

ALTER SYSTEM SET PGA_AGGREGATE_LIMIT=8G SCOPE=SPFILE;

2、核心指标:工作区执行方式

Oracle 将工作区执行分为三种方式:

  • Optimal:所有操作都在内存中完成,性能最好
  • One-pass:需要将部分数据写入临时表空间,性能中等
  • Multi-pass:需要多次读写临时表空间,性能极差

优化目标:Optimal 执行比例 > 90%,One-pass<10%,完全避免 Multi-pass。

sql 复制代码
-- 1. 查看PGA整体使用情况
SELECT 
  name,
  value/1024/1024 AS value_mb
FROM v$pgastat
WHERE name IN (
  'total PGA allocated',
  'total PGA inuse',
  'maximum PGA allocated'
);

-- 2. 查看工作区执行统计(最核心)
SELECT 
  optimal_executions,
  onepass_executions,
  multipasses_executions,
  ROUND(optimal_executions/(optimal_executions+onepass_executions+multipasses_executions)*100, 2) AS optimal_pct
FROM v$pgastat
WHERE name IN ('optimal executions', 'onepass executions', 'multipasses executions');

-- 3. 查看PGA使用TOP 10进程
SELECT 
  s.sid,
  s.serial#,
  s.username,
  s.program,
  ROUND(p.pga_alloc_mem/1024/1024, 2) AS pga_alloc_mb,
  ROUND(p.pga_used_mem/1024/1024, 2) AS pga_used_mb
FROM v$session s
JOIN v$process p ON s.paddr = p.addr
WHERE s.username IS NOT NULL
ORDER BY p.pga_alloc_mem DESC
FETCH FIRST 10 ROWS ONLY;

-- 4. 查看当前活跃的大工作区
SELECT 
  sql_id,
  operation_type,
  expected_size/1024/1024 AS expected_mb,
  actual_mem_used/1024/1024 AS actual_mb,
  number_passes
FROM v$sql_workarea_active
ORDER BY actual_mem_used DESC;

3、优化方法

调整 PGA_AGGREGATE_TARGET 大小:

查看PGA大小建议:

SELECT pga_target_for_estimate, pga_target_factor, estd_time FROM v$pga_target_advice;

设置原则

  • OLTP 系统:PGA_AGGREGATE_TARGET = 总内存 × 20-30%
  • OLAP 系统:PGA_AGGREGATE_TARGET = 总内存 × 30-40%
  • PGA_AGGREGATE_LIMIT = PGA_AGGREGATE_TARGET × 2

优化排序操作:

排序是消耗 PGA 最多的操作,也是最容易优化的操作:

a、在排序列上创建索引:利用索引的有序性避免排序

避免ORDER BY排序:CREATE INDEX idx_orders_order_date ON orders(order_date) ONLINE;

b、只排序需要的列:避免 SELECT *

c、减少排序的数据量:尽早使用 WHERE 条件过滤数据

d、避免不必要的排序:去掉多余的 ORDER BY、DISTINCT 和 UNION(改用 UNION ALL)

优化哈希连接:

  • 小表驱动大表:让小表作为哈希表,减少内存消耗
  • 在连接列上创建索引:减少连接的数据量
  • 避免大表之间的哈希连接:改用嵌套循环连接或分区裁剪

实例:PGA 不足导致月底报表超时

S(Situation - 情境): 某公司 ERP 系统月底成本核算报表执行时间从 15 分钟飙升至 3 小时。AWR 显示direct path write temp等待事件占总等待时间的 85%,Multi-pass 执行比例达到 12%。

**T(Task - 任务):**1 小时内优化 PGA,确保当天完成报表。

A(Action - 行动):

1、在线调整 PGA_AGGREGATE_TARGET 从 2GB 增至 8GB

2、设置 PGA_AGGREGATE_LIMIT=16GB

3、杀掉正在执行的慢报表进程,重新执行

**R(Result - 结果):**报表执行时间从 3 小时缩短至 12 分钟,Optimal 执行比例从 78% 提升至 96%,并将Multi-pass 执行比例降至 0%,最终当天顺利完成月底成本核算。

相关推荐
IT邦德1 小时前
Oracle 26ai RAC 通过gold image RU打补丁
数据库·oracle
Minxinbb2 小时前
TDSQL for MySQL部署选型
数据库·dba
C137的本贾尼2 小时前
【实战】实现一个带事务与索引的命令行图书借阅系统
数据库·microsoft·oracle
jnrjian1 天前
TDE HSM SET ENCRYPTION KEY
oracle
六月雨滴1 天前
Oracle 内存优化
数据库·oracle
mN9B2uk171 天前
数据库锁总结
数据库·oracle
闪电悠米1 天前
黑马点评-秒杀优化-03_blocking_queue_async_order
数据库·分布式·oracle·junit·wpf·lua
abcy0712132 天前
pycharm python sqlalchemy mysql增删改查实例csdn
数据库·oracle
烟雨归来2 天前
生僻字乱码解决方案,NVARCHAR2改造踩坑记录
oracle