Oracle 19c启用In-Memory必须设置INMEMORY_SIZE≥100M并重启数据库,CDB级配置生效,通过V$INMEMORY_AREA和V$INMEMORY_SEGMENTS确认实际加载状态,且SQL需匹配条件才能触发INMEMORY访问。
Oracle 19c 中 INMEMORY_SIZE 必须大于 0 才能启用 In-Memory
oracle 19c 的 in-memory 选项默认是关闭的,哪怕你给表加了 inmemory 属性,只要 inmemory_size 是 0,数据就根本不会进内存。这不是延迟加载,是彻底不启动模块。
-
INMEMORY_SIZE是一个静态参数(SPFILE级别),修改后必须重启数据库才能生效;动态设置会报错ORA-02095: specified initialization parameter cannot be modified - 最小有效值是
100M(不是 1M 或 0),低于这个值 Oracle 会静默忽略 In-Memory 功能 - 如果用的是多租户架构(CDB),
INMEMORY_SIZE必须在 CDB 级别设置,PDB 里设无效;但每个 PDB 可以通过ALTER PLUGGABLE DATABASE ... SET INMEMORY_QUERY = ENABLE单独控制是否允许查询走 In-Memory
怎么确认 INMEMORY_SIZE 已真正生效
光看 SHOW PARAMETER INMEMORY_SIZE 不够,它只显示参数值,不反映实际运行状态。得查底层视图才能确认 In-Memory 区域是否被分配和使用。
- 执行
SELECT * FROM V$INMEMORY_AREA:如果返回空行,说明 In-Memory 没激活;有记录且ALLOCATED_BYTES > 0才算成功分配 - 查
V$INMEMORY_SEGMENTS看哪些对象进了内存——刚设完参数、没触发加载时,这张表也可能是空的;需要对目标表做一次全表扫描或执行SELECT /*+ INMEMORY */ COUNT(*) FROM your_table才会触发加载 - 注意
V$INMEMORY_AREA中的POPULATE_STATUS字段:如果是COMPLETED表示已加载完成,NOT POPULATED不代表失败,只是还没开始加载
INMEMORY 表属性和压缩级别影响内存占用与查询性能
表级 INMEMORY 不是开个开关就完事,不同压缩级别直接决定实际内存消耗和扫描速度,而且不是越高越好。
- 默认是
MEMCOMPRESS FOR QUERY LOW,适合 OLAP 类聚合查询;如果字段重复度高(比如状态码、地区编码),用FOR CAPACITY HIGH能省 40%+ 内存,但解压开销略增 - 别在索引组织表(IOT)或全局临时表(GTT)上设
INMEMORY,Oracle 会报ORA-64307: hybrid columnar compression is not supported for this object type - 对大宽表,建议只对高频过滤/聚合字段启用
INMEMORY,例如:ALTER TABLE sales INMEMORY (prod_id, time_id, amount_sold),避免整张表全量加载吃光内存
常见错误:启用了 In-Memory 却查不到加速效果
最典型的现象是执行计划里看不到 TABLE ACCESS INMEMORY FULL,或者 V$SQL 中对应 SQL 的 INMEMORY 列为 NO。
- 检查是否用了绑定变量且未开启自适应游标共享(ACS):某些场景下 Oracle 会因绑定变量窥探失败而跳过 In-Memory 访问路径
- 确认 SQL 没触发隐式类型转换,比如
WHERE date_col = '2023-01-01'(字符串 vs DATE),会导致无法使用 In-Memory 存储格式 - 并行查询(
PX)默认不走 In-Memory,除非显式加上提示/*+ INMEMORY */或设置ALTER SESSION SET INMEMORY_QUERY = ENABLE - 如果表上有函数索引或虚拟列,且查询条件涉及这些列,In-Memory 加载可能被绕过——得查
V$INMEMORY_EXPRESSIONS确认表达式是否被支持
配置这事没有“设完就跑”,INMEMORY_SIZE 的值、表的加载策略、SQL 的写法,三者必须咬合。最容易被跳过的其实是加载触发时机——没人扫表,Oracle 就真不加载,连错误都不会报。

















