ITPub博客

首页 > 数据库 > Oracle > In-memory不要全加载怎么做?

In-memory不要全加载怎么做?

原创 Oracle 作者:xuexiaogang 时间:2025-08-05 19:27:51 0 删除 编辑

In-memory这个功能都有十多年了

  • 大家都知道alter table t INMEMORY,这一个命令就让Oracle数据库实现了行列混存。没什么特别的点。
  • 但是最近我遇到了一个问题,就是需要部分列加载

有些问题深耕一下会发现不一样的

  • 为什么要深耕一下?是因为我要加载部分列。
  • 为什么不全部加载?那是因为内存有限。一个表中仅仅有2-3个字段需要聚合。全部加载浪费内存。
  • 全部加载会很大吗?会的,当你见过一个表有200个字段或者400个字段的时候你就明白了。实际用到的聚合字段连百分之一都不到。

实验先说全部加载(好和后面部分加载对比)

  • 做两个从表结构到数据一模一样的表

  • image.png

  • 开始查询表未以列式存储加载到内存中

  • USED_BYTES是0
    image.png

  • 执行一个命令把full表全部加载

  • alter table FULL inmemory;

  • 然后观看执行计划已经识别到了(而且在 v$im_column_level 的数据字典中都看到5列全部识别)
    image.png

  • 但是其实并没有加载到内存(可以看到实际占用还是0)

  • image.png

  • 需要触发一下。

  • 比如执行一个select * from FULL;

  • 可以看到USED_BYTES在不断变化。OPULATE_STATUS也在变化,直到加载完毕。我把这个过程记录了下来。

  • Oracle就是一定要触发一下。
    image.png

  • 执行一下,需要50毫秒就完成了。900万数据聚合。

  • image.png

实验说明如何部分加载

  • 这次另外建立一个表big
  • 要执行两步,第一步加载表,第二步指明那些要,哪些不要。(其实看到这两步,我就明白了,为什么Oracle设计为什么要手工触发再加载。因为如果一个命令就加载,那么要做排除的话,还要把刚才加载的做卸载,很多就白做了)
  • alter table big inmemory;
  • alter table big no inmemory (id,name,time,m) inmemory (n);

image.png

  • 手工执行触发一下。

image.png

两者对比

  • full表执行count(*)和 sum(n)任意一列都可以用到列存计算

  • image.png

  • big表执行sum(n)可以用到列存计算而执行 sum(n)不可以,因为m列没有加载

  • image.png

  • 查询数据字典也可以看到两者占内存大小不一样

  • image.png


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/637517/viewspace-3092825/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
OracleACE/PostgreSQLACE/阿里云MVP/腾讯云TVP/墨天轮 MVP/TiDBMVA/数盟会华东区长老/OpenTenBase社区委和技术委委员/架构师技术同盟名人堂成员上海地区理事会成员/if社区联合发起人/《DBA实战手记》作者/公众号:四海内皆兄弟

注册时间:2013-07-01

  • 博文量
    422
  • 访问量
    953229