ADG备库启用In-Memory前必须确认三件事:一是inmemory_size参数非零(默认为0,未显式配置即未启用);二是inmemory_adg_enabled=TRUE(19c默认开启,但仅表示允许启用);三是若为RAC环境,需确保parallel_degree_policy=AUTO且parallel_force_local=FALSE,否则IM列存储不参与并行查询。
ADG备库启用In-Memory前必须确认的三件事
adg备库默认不自动启用in-memory,即使主库开了,备库也几乎肯定没生效——因为inmemory_size是实例级静态参数,备库启动时若未显式配置,值为0;且inmemory_adg_enabled虽默认为true,但只是“允许启用”,不是“自动启用”。
- 查备库当前状态:
SHOW PARAMETER inmemory_size,结果为0就说明完全未启用 - 确认
inmemory_adg_enabled = TRUE(该参数不可动态改,但19c默认已开) - 检查备库是否为RAC:若是,还需确保
parallel_degree_policy = AUTO且parallel_force_local = FALSE,否则IM列存储不会参与并行查询
给备库分配In-Memory内存的实操步骤
不能直接在备库上执行ALTER SYSTEM SET inmemory_size=... SCOPE=SPFILE后重启——ADG备库的SPFILE通常由主库管理,手动改可能被主库后续操作覆盖。正确做法是通过主库统一管控或使用PDB级参数。
- 若用CDB/PDB架构:在备库的PDB中执行
ALTER SYSTEM SET inmemory_size=8G SCOPE=SPFILE,再重启该PDB(不影响CDB和其他PDB) - 若为非CDB或需全局生效:必须在主库修改SPFILE,并触发备库参数同步(依赖
LOG_ARCHIVE_CONFIG和DG Broker配置完整性) - 分配大小建议从4G起步,不超过物理内存的25%;避免设过大导致
ORA-04030(进程内存耗尽),尤其当备库同时跑MRP和大量只读查询时
让表真正进内存:不是ALTER TABLE就完事
ALTER TABLE sales INMEMORY只是声明“这个表可以进内存”,不等于立刻加载。备库上数据加载行为与主库不同:它不会回放主库的IM加载动作,必须在备库本地触发首次访问或显式预热。
- 首次查询会触发异步加载,但首条SQL会慢(因要从磁盘读+解压+列转存),这不是bug,是设计使然
- 主动预热更可控:执行
EXEC DBMS_INMEMORY.POPULATE('SALES'),注意该过程占用CPU和IM内存,避开业务高峰 - 验证是否加载成功:
SELECT segment_name, populate_status FROM v$im_segments WHERE segment_name = 'SALES',状态为COMPLETED才算落地 - 别忽略压缩策略:对分析型大表,用
MEMCOMPRESS FOR CAPACITY HIGH比默认QUERY LOW节省约40%内存,但解压CPU开销略升
为什么备库查得快,但执行计划里看不到INMEMORY FULL?
常见现象:表明明在v$im_segments里显示COMPLETED,可执行计划却还是TABLE ACCESS STORAGE FULL,甚至走索引扫描。根本原因不是IM没生效,而是优化器没选它——通常卡在两个地方。
-
optimizer_inmemory_aware = FALSE:该参数控制优化器是否感知IM存在,必须为TRUE(19c默认是,但备库若从老版本升级可能残留FALSE) - 谓词不匹配IM加速场景:IM擅长
=、IN、范围扫描少量列;若SQL含LIKE '%xxx'、函数索引字段(如UPPER(name))、或SELECT *取全部50列,优化器大概率弃用IM路径 - 统计信息陈旧:
DBMS_STATS.GATHER_TABLE_STATS必须在IM加载**之后**再收集一次,否则优化器基于旧行存统计估算成本,误判IM路径更贵
最易被忽略的一点:ADG备库上QUERY_REWRITE_INTEGRITY若为enforced(默认),会导致涉及物化视图或外部表的IM查询被绕过;分析类查询建议临时设为stale_tolerated,但需评估一致性风险。











