在Oracle 19c中怎样通过AWR报告监控索引的使用频率与效率?

作者:袖梨 2026-07-15
AWR报告不记录索引使用频次,需结合dba_hist_seg_stat(过滤INDEX、排除系统对象、窄时间窗口)与ASH下钻执行计划才能准确判断索引是否高效使用。

awr报告本身不记录索引被用了多少次,只提供段级聚合数据;要判断索引是否真被高效使用,必须交叉比对segments by logical readssegments by physical readssegments by buffer busy waits,再下钻到dba_hist_seg_stat过滤object_type = 'index',否则全是干扰项。

怎么看索引是不是被高频扫描

直接翻AWR报告里的Segment Statistics表格没用——它默认只列top 5,且不区分对象类型。真正信号藏在基表里:

  • dba_hist_seg_stat,加条件statistic_name IN ('physical reads', 'logical reads'),别漏掉logical reads
  • JOIN dba_objects时用dataobj#匹配object_id(分区索引必须这么连,否则查不到子分区)
  • 过滤OBJECT_TYPE = 'INDEX'OWNER NOT IN ('SYS','SYSTEM','XDB'),排除系统对象
  • 时间窗口要窄:snap_id BETWEEN 1234 AND 1235,避免跨天聚合把偶发扫描放大成常态

为什么物理读高不等于索引设计错

一个索引physical reads高,可能是主键等值查询的合理行为;但若它的physical reads远高于对应基表,就危险了:

  • 先看访问模式:access_predicates为空?说明SQL谓词根本没走索引(比如WHERE UPPER(name) = 'ABC'
  • clustering_factor:如果接近表行数,说明数据物理分布和索引顺序严重偏离,范围扫描代价飙升
  • 检查绑定变量值是否导致计划倾斜——某次执行用了极低选择性值走了索引,后续被缓存复用,实际多数情况不该走
  • physical reads direct高的索引通常不是被扫描,而是被并行DML或大查询直读,这种读不进buffer cache,也不会体现在logical reads

AWR不够准,必须用ASH补盲区

Segments by Logical Reads无法区分“一次高效索引唯一扫描”和“一万次低效范围扫描+回表”,更掩盖不了执行计划变更的影响:

  • 关联ash.sql_iddba_hist_sql_planplan_table_output,过滤operationINDEX的行
  • 重点看access_predicatesfilter_predicates是否匹配SQL谓词,尤其注意函数索引是否被真正命中
  • 如果Buffer Busy Waits高,不一定是索引热块争用——反向键索引在高并发插入时也会触发叶块争用,根源不在查询逻辑

最易忽略的是:AWR里看到的索引读数,可能来自全表扫描后的回表操作,而不是索引本身被驱动;没有ASH下钻确认执行计划分支,单看Segment Statistics就是雾里看花。

相关文章

精彩推荐