SGA(系统全局区)是 Oracle 数据库所有进程共享的核心内存区域,负责缓存数据块、SQL 执行计划、重做日志等关键信息。SGA 优化的本质是让尽可能多的热点数据和代码常驻内存,将磁盘 IO 减少到最低,从而将数据库整体性能提升 10-100 倍。
1、SGA 基础
1.1、什么是 SGA 优化
SGA 优化是通过调整内存管理模式、分配 SGA 总大小、优化各组件资源配比和操作系统内存配置,实现三个核心目标:
- 提高缓存命中率:缓冲区命中率 > 95%,库缓存命中率 > 99%
- 避免内存交换:SGA 完全驻留在物理内存中,不被交换到磁盘
- 消除内存争用:解决缓冲池、共享池等组件的锁竞争问题
1.2、SGA 内存架构
SGA(所有进程共享)
- 数据库缓冲池(Database Buffer Cache):占比50-70%,缓存数据块(最核心)
- DEFAULT池:默认缓冲池
- KEEP池:缓存频繁访问的小表/索引
- RECYCLE池:缓存偶尔访问的大表
- 共享池(Shared Pool):占比15-25%,缓存SQL执行计划和数据字典
- 库缓存(Library Cache):SQL/PL/SQL执行计划
- 字典缓存(Row Cache):数据字典信息
- 重做日志缓冲区(Redo Log Buffer):占比1-2%,缓存重做日志
- 大池(Large Pool):RMAN备份、并行查询、共享服务器
- Java池(Java Pool):Java程序执行
- 流池(Streams Pool):Oracle Streams、GoldenGate
1.3、SGA 优化核心原则
- 内存优先原则:SGA 占物理内存的 50-70%,至少保留 20% 给操作系统
- 自动管理优先:生产环境使用 ASMM 模式,禁止手动管理
- 大页必配原则:所有 Linux 生产环境必须配置大页,禁用透明大页
- 按需分配原则:OLTP 系统侧重缓冲池,OLAP 系统侧重共享池和大池
2、核心组件优化
2.1、数据库缓冲池优化
数据库缓冲池缓存了从磁盘读取的数据块,是 SGA 中最大的组件,通常占 SGA 的 40-60%。
核心指标:缓冲区命中率:
计算缓冲区命中率:
SELECT
ROUND(1 - (physical_reads / (db_block_gets + consistent_gets)) * 100, 2) AS buffer_hit_ratio
FROM v$buffer_pool_statistics
WHERE name = 'DEFAULT';
命中率标准:
- 优秀:>99%
- 良好:95-99%
- 需优化:<95%
优化方法:
1、调整缓冲池大小
查看缓冲池大小建议:
SELECT size_for_estimate, buffers_for_estimate, estd_physical_read_factor
FROM v$db_cache_advice;
-- 调整缓冲池大小
ALTER SYSTEM SET DB_CACHE_SIZE=8G SCOPE=BOTH;
2、使用多缓冲池
- DEFAULT 池:默认缓冲池,存储大多数数据
- KEEP 池:存储频繁访问的小表和索引,避免被换出
- RECYCLE 池:存储偶尔访问的大表,避免污染默认池
创建KEEP池和RECYCLE池:
ALTER SYSTEM SET DB_KEEP_CACHE_SIZE=1G SCOPE=BOTH;
ALTER SYSTEM SET DB_RECYCLE_CACHE_SIZE=2G SCOPE=BOTH;
将表分配到KEEP池:
ALTER TABLE emp STORAGE (BUFFER_POOL KEEP);
将表分配到RECYCLE池:
ALTER TABLE large_table STORAGE (BUFFER_POOL RECYCLE);
3、调整大小
- OLTP 系统:使用 8KB 或 16KB 块大小
- OLAP 系统:使用 32KB 或 64KB 块大小
2.2、共享池优化
共享池缓存了 SQL 执行计划、PL/SQL 代码和数据字典信息,通常占 SGA 的 15-25%。
核心指标:库缓存命中率和字典缓存命中率:
库缓存命中率:
SELECT ROUND(1 - (reloads / pins) * 100, 2) AS library_cache_hit_ratio
FROM v$librarycache;
字典缓存命中率:
SELECT ROUND(1 - (getmisses / gets) * 100, 2) AS dictionary_cache_hit_ratio
FROM v$rowcache;
命中率标准:
- 库缓存命中率:>99%
- 字典缓存命中率:>95%
优化方法:
1、使用绑定变量:避免硬解析,这是共享池优化最重要的方法
不好的写法:每次执行都硬解析
SELECT * FROM emp WHERE empno=7369;
SELECT * FROM emp WHERE empno=7370;
好的写法:使用绑定变量,只硬解析一次
SELECT * FROM emp WHERE empno=:empno;
2、调整共享池大小:
查看共享池大小建议:
SELECT size_for_estimate, estd_lc_size, estd_lc_memory_objects
FROM v$shared_pool_advice;
调整共享池大小:
ALTER SYSTEM SET SHARED_POOL_SIZE=2G SCOPE=BOTH;
3、设置 CURSOR_SHARING 参数:
强制将字面量转换为绑定变量(临时解决方案):
ALTER SYSTEM SET CURSOR_SHARING=FORCE SCOPE=BOTH;
4、解决 ORA-04031 错误:
刷新共享池(临时解决):
ALTER SYSTEM FLUSH SHARED_POOL;
永久解决:增大共享池大小,优化SQL使用绑定变量
2.3、重做日志缓冲区优化
重做日志缓冲区缓存了即将写入磁盘的重做日志,通常设置为 64MB-256MB。
优化方法:
设置重做日志缓冲区大小:
ALTER SYSTEM SET LOG_BUFFER=64M SCOPE=SPFILE;
注意:重做日志缓冲区不是越大越好,超过 128MB 后性能提升不明显。
2.4、大池优化
大池用于 RMAN 备份、并行查询和共享服务器模式,通常设置为 100MB-1GB。
设置大池大小:
ALTER SYSTEM SET LARGE_POOL_SIZE=512M SCOPE=BOTH;
实例:大池不足导致 RMAN 备份超时
S(Situation - 情境): 某公司核心数据库每日全量备份时间从 2 小时延长至 6 小时,超出备份窗口。RMAN 日志显示大量 ORA-04031: unable to allocate 4194320 bytes of shared memory ("large pool") 错误。大池仅配置 100MB,RMAN 使用 4 个并行通道。
**T(Task - 任务):**当天解决备份超时问题,不影响夜间业务。
A(Action - 行动):
1、在线调整大池大小从 100MB 增至 2GB:ALTER SYSTEM SET LARGE_POOL_SIZE=2G SCOPE=BOTH;
2、调整 RMAN 并行通道数从 4 个增至 8 个
3、重新执行备份验证
**R(Result - 结果):**备份时间从 6 小时缩短至 1 小时 40 分钟,并不再出现 ORA-04031 错误,最终备份窗口完全满足业务要求。