Oracle SGA 优化

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 错误,最终备份窗口完全满足业务要求。

相关推荐
ClouGence5 天前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
ClouGence11 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
曹牧12 天前
Oracle EXPLAIN PLAN
数据库·oracle
贤时间12 天前
codex 助力oracle ebs 开发
数据库·oracle
秉承初心12 天前
PostgreSQL 数据性能瓶颈突破实战
数据库·postgresql·oracle
Curvatureflight12 天前
MySQL 深分页越来越慢?从 LIMIT OFFSET 改成游标分页
数据库·oracle
XZ-07000112 天前
MySQL事务
数据库·mysql·oracle
tiancaijiben12 天前
阿里云函数计算FC如何实现网站的定时任务与自动化
数据库·oracle·dba
xfhuangfu12 天前
Oracle 19c 多租户体系架构介绍
数据库·oracle·架构
杨云龙UP12 天前
Spotlight 接入 Oracle 数据库监控操作指南 2026-06-16
数据库·oracle·性能监控·预警·阈值·spotlight·瓶颈分析