应优先查看AWR报告中Segment Statistics章节的Physical Reads列,它反映采样周期内段从磁盘读取的总块数,口径与执行计划一致;注意区分Logical Reads、关注业务Owner、结合dba_hist_seg_stat下钻分析,并排查TEMP/UNDO段干扰。
查 Physical Reads 排名靠前的段,直接看 SEGMENT STATISTICS 部分
awr 报告里「segment statistics」章节默认只显示 top 5 的物理读、逻辑读等指标。很多人翻半天没找到高物理读对象,其实是没注意这个部分默认折叠、且排序依据是「该快照周期内累计值」,不是单次 sql 的瞬时峰值。
打开 awr 报告后,直接搜索 segment statistics,定位到子节 physical reads —— 这才是你真正要盯的列。它反映的是该段在采样周期内被数据库从磁盘读取的总块数(db file sequential read + db file scattered read),和执行计划里的 physical reads 字段口径一致。
常见错误现象:
• 把 Logical Reads 当成瓶颈(其实缓存命中高,物理 I/O 并不高)
• 只看 Executions 多的 SQL,但没关联到它访问的段
• 忽略 Owner 列,误把系统表(如 sys 下的 seg$)当成业务对象
- 优先关注
Owner是业务 Schema(比如SCOTT、HR)的行 - 对比同一段在多个 AWR 周期的
Physical Reads增长趋势,排除偶发抖动 - 若某索引的物理读远高于其基表,说明该索引可能被大量用于低效范围扫描或未走索引的谓词回表
用 dba_hist_seg_stat 手动查更细粒度数据
AWR 报告里的 Segment Statistics 是汇总视图,字段少、不可过滤。真要定位“哪个时间段突增”“是不是某个分区在拖累”,得下钻到基表 dba_hist_seg_stat。它按 dbid、instance_number、snap_id、obj# 记录每段每小时的统计增量,比报告灵活得多。
使用场景:
• 比对两个相邻 AWR 快照,确认物理读激增是否真实(避免因快照间隔不均造成误判)
• 关联 dba_objects 查出具体对象名和类型(OBJECT_TYPE = 'TABLE' OR 'INDEX')
• 加 WHERE snap_id BETWEEN X AND Y 聚焦问题窗口
-
statistic_name = 'physical reads'是你要过滤的关键字段,别错写成'physical reads direct'(那是直读,通常和大表扫描或并行有关) -
dataobj#和obj#区别:前者对应分区对象(如分区表的子分区),后者是主对象编号;查分区表时优先用dataobj#关联dba_objects.object_id - 注意
dba_hist_seg_stat默认只保留 8 天(由DBA_HIST_WR_CONTROL.retention控制),过期数据查不到
Physical Reads 高 ≠ 表设计有问题,先看访问模式
一个表物理读高,可能是坏信号,也可能是合理行为。比如批处理作业每天凌晨全表扫描一次,Physical Reads 必然高,但只要不卡住在线业务,就不是紧急问题。关键要看这些读来自哪里、是否可优化。
容易踩的坑:
• 看到 INDEX 物理读高,立刻删索引——其实可能是该索引支撑了关键查询,删了反而让基表全扫
• 把 lobsegment 或 lobindex 的高物理读当普通表处理,忽略 LOB 缓存策略(cache/nocache)的影响
• 用 db file sequential read 等待事件反推,却没结合执行计划看是单块读(索引查找)还是多块读(全表扫描)
- 用
v$active_session_history或 ASH 报告,按current_obj#关联,找出哪些 SQL 正在频繁访问该段 - 检查对应 SQL 的执行计划:如果走
INDEX RANGE SCAN但Physical Reads高,大概率是索引选择性差或回表多;如果是TABLE ACCESS FULL,再查是否缺索引或统计信息陈旧 - 对大表,确认是否启用了
cell flash cache(Exadata)或buffer pool keep,否则热数据也反复物理读
别漏掉 TEMP 和 UNDO 段的物理读干扰
默认情况下,SEGMENT STATISTICS 不显示临时段和回滚段——但它们的物理读会真实发生,且可能占总量不小比例。尤其当看到整体 physical reads 很高,但业务表/索引加起来占比不到 70%,就得怀疑是不是排序、哈希连接或大事务把 temp 或 undo 撑爆了。
验证方法:
• 在 AWR 报告中翻到 «Wait Events» 部分,看 direct path write temp 或 log file sync 是否异常高
• 查询 dba_hist_seg_stat 时加上 owner IN ('SYS', 'SYSTEM'),过滤出 TEMP 表空间下的 SEGMENT_NAME(通常是 SYS_LOB* 或 ORA$TEMPSEG*)
-
TEMP段物理读高,往往意味着 SQL 使用了大量内存外排序(sort_area_size小或 PGA_AGGREGATE_LIMIT 限制严) -
UNDO段物理读高,常见于长事务未提交,导致其他会话需要 consistent read 回滚段数据块 - 这类段不会出现在业务监控列表里,但会拉高整体 I/O,排查时容易绕远路










