不能准确定位热点表,因logical reads高可能源于系统内部访问、小配置表高频扫描或全表扫描空块,不反映真实业务压力;需过滤业务schema、关注绝对值(如>500万/小时且翻倍)、并交叉验证physical reads。
直接看 segments by logical reads 不能准确定位“热点表”,它只告诉你谁被读得最勤,不区分访问方式、效率或是否真在服务业务请求。
为什么Logical Reads高 ≠ 表真的热
逻辑读高常来自三类干扰:系统内部访问(如 OBJ$、IND$)、小而高频的配置表(如状态码表)、或全表扫描扫出大量空块。这些读本身不体现业务压力,也不代表该表是性能瓶颈源。
-
Segments by Logical Reads统计的是段级块访问次数,不关联 SQL 谓词、执行计划或实际返回行数 - 一张只有 100 行的表,被 50 个会话每秒全扫一次,逻辑读轻松上百万,但它可能根本没锁争用、没物理 I/O、也没缓冲区等待
- 索引段排在前列,但对应 SQL 可能根本没走索引——比如写了
UPPER(name) = 'ABC'却没建函数索引,AWR 仍会把逻辑读记到基表段上
怎么筛出真正值得查的业务表
重点不是数值最大,而是“异常 + 业务归属 + 可验证”:
- 过滤
Owner列,只留你自己的 Schema(如SCOTT、HR),跳过SYS、SYSTEM、DBSNMP - 看绝对值:单个表逻辑读 > 500 万/小时,且比基线周期翻倍以上,才进入排查范围
- 交叉核对
Segments by Physical Reads:如果逻辑读高但物理读极低(Physical Reads / Logical Reads - 顺藤摸瓜进
SQL ordered by Gets页面,用 Ctrl+F 搜该表名,确认是否有真实业务 SQL 在驱动这些读
下一步必须做的验证动作
看到一个表在 Segments by Logical Reads 排前三,别急着重建或分区。先跑两件事:
- 查
DBA_HIST_SEG_STAT,按logical_reads_delta和buffer_busy_waits_delta双排序,确认是否同时存在高争用:“热”且“堵”才是真热点 - 执行
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('sql_id')),挑出访问该表的 top SQL,看执行计划里是不是 NL Join 驱动端、是不是 index range scan + 大量回表、有没有 filter 前置导致全扫 - 检查该表的
dba_tables.num_rows和avg_row_len,算下理论最小块数;再对比user_extents.blocks,若实际分配块数是理论值 3 倍以上,才考虑碎片,而不是逻辑读本身
逻辑读只是入口信号,不是诊断结论。真正要盯的是“谁在读、怎么读、读完干了什么”。AWR 不告诉你执行计划退化,也不记录谓词是否命中索引前缀——这些都得靠下钻和人工比对。











