Oracle关于12C新特性In-Memory踩坑历程
关于In-Memory的介绍网上比较多,这里列出一些刚学习踩到的一些坑。
- 和ClickHouse的表采用列式存储不同,Oracle的In-Memory(DBIM)特性还是按照行来存储的,只不过专门开辟一块内存区域作为纯列式存储(大小由INMEMORY_SIZE控制)。列存储不会取代传统的缓冲区缓存,而是作为一种补充。
一开始还以为DBIM特性是会让表实际在磁盘块中就按照列式来存储。 - 由于还是按照行存储,因此如果是第一次查询触发了加载表到IM内存区域的话速度还是会比较慢的。
加载这个动作称为populate。那么如何确定表被populate到IM内存呢?
查看v$im_segments.bytes_not_populated字段来确定。 - populate到IM内存的时候会进行压缩,默认压缩级别为:FOR QUERY LOW
试过40多G的表使用默认压缩级别的话,导致无法全部populate进去4G大小的IM内存。
也就是查询v$im_segments.bytes_not_populated的值一直不为0,导致我针对表的查询一直产生大量的物理读也就是DBIM没完全生效。
之后改成CAPACITY HIGH就可以了。 - v$im_segments.bytes_not_populated不为0的原因可以参考MOS文档:Why do Objects not Load into the In-memory Column Store when Using the Database In-Memory (DBIM) Option? (文档 ID 2232741.1)
- populate进去IM内存有几种方式:全表扫描进去,DBMS_INMEMORY进去,设置PRIORITY clause(见下表)自动加载数据
- RAC中使用DBIM需要注意的点:在ORACLE 12C RAC中使用in memory特性请注意parallel_degree_policy和parallel_force_local参数
- 涉及的视图:v$im_segments,v$inmemory_area,v$im_column_level
参考链接
Why does BYTES_NOT_POPULATED suddenly show a non-zero value?