AWR不直接标记SQL是否使用In-Memory,需通过对比IM启用前后Physical Reads、Buffer Gets、Elapsed Time及执行计划中INMEMORY关键字(如TABLE ACCESS INMEMORY FULL)等指标差异来判断收益。

开启In-Memory后,AWR本身不直接标记某条SQL是否用了IM列存,也不能告诉你“用了IM就快了X倍”——收益必须靠对比分析:同一SQL在IM启用前后,逻辑读、物理读、执行时间、执行计划访问路径的差异来交叉判断。
查AWR里有没有IM相关的等待事件或统计项
Oracle 19c AWR报告中没有名为inmemory的等待事件,也没有IM scan类专用指标。你不会在Top 5 Timed Foreground Events里看到它,在Instance Efficiency Percentages里也找不到IM命中率。AWR只记录结果,不标注原因。所以别浪费时间翻“Wait Events”找IM线索。
真正能间接反映IM生效的,是以下三处:
-
Physical Reads和Physical Reads Direct是否同步大幅下降(尤其对原本全表扫描的SQL) -
Buffer Gets明显升高但响应时间没涨——说明数据从IM Area读取,走了列式扫描+向量化处理,逻辑读变多但延迟低 -
DB CPU占比上升 +Elapsed Time Per Exec下降 → IM加速了CPU-bound操作(如聚合、过滤),而非IO-bound
用DBA_HIST_SQLSTAT对比IM启用前后的关键指标
最可靠的方式是写SQL查历史统计,锁定目标SQL_ID,对比IM开关前后两个时间段的执行特征:
- 执行前先确认IM已生效:
SELECT inmemory FROM dba_tables WHERE table_name = 'YOUR_TABLE'返回ENABLED - 查IM启用前(比如快照ID 1000–1010)的基准值:
SELECT executions, buffer_gets, disk_reads, elapsed_time/1000000 elapsed_sec FROM dba_hist_sqlstat WHERE sql_id = 'xxx' AND snap_id BETWEEN 1000 AND 1010 - 再查启用后(比如快照ID 1100–1110)的值,重点看:
disk_reads是否趋近于0、buffer_gets是否跳升、elapsed_sec/executions是否显著缩短 - 注意过滤掉
executions = 0或disk_reads IS NULL的无效行——AWR采样可能漏掉某些执行
通过DISPLAY_AWR确认执行计划是否走了IM扫描
AWR不存执行计划的“是否IM”标记,但执行计划文本里有明确线索:
- 运行
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('sql_id', NULL, NULL, 'ADVANCED')) - 在Plan部分找
INMEMORY关键字:如果出现TABLE ACCESS INMEMORY FULL或INMEMORY JOIN,说明该次执行确实用了IM列存 - 如果只看到
TABLE ACCESS FULL或INDEX RANGE SCAN,哪怕IM已开,这条SQL也没走IM——可能是谓词未覆盖IM列、或/*+ NO_INMEMORY */提示被硬编码进应用 - 注意:同一
sql_id下不同plan_hash_value可能对应IM和非IM两种路径,得逐个查plan_hash_value确认
最容易被忽略的收益陷阱:IM不是万能加速器
很多团队开了IM就以为全表扫描自动变快,结果AWR里Elapsed Time Per Exec没变化,甚至更慢——问题往往出在:
- 表虽启用了
INMEMORY,但实际加载进度为0:SELECT populate_status, bytes_not_populated FROM v$im_user_segments WHERE segment_name = 'T'返回POPULATING或大量bytes_not_populated - 查询用了
ORDER BY或GROUP BY且字段不在IM列中,触发回退到buffer cache或磁盘读 - 并行度设得过高,IM扫描反被PX进程调度开销抵消,
DB CPU飙升但AAS没降 - AWR快照间隔太长(比如1小时),而IM加载是渐进过程,单次快照抓不到“刚加载完那几分钟”的性能跃升


















