直接查v$session定位正在等待的SQL和热点块,执行SELECT sid, sql_id, p1 "file#", p2 "block#", p3 "class#" FROM v$session WHERE event = 'read by other session',观察是否高度集中;若分散则多为SQL分布问题,若集中则锁定具体段对象,再依db file scattered/sequential read类型差异分别优化执行计划或索引设计。

直接查v$session定位正在等待的SQL和热点块
别先看AWR报告里“累计等待时间最长”就下结论——read by other session 是瞬时争用,AWR只统计汇总,容易掩盖真实热点。最有效动作是立刻抓活会话:
- 执行
SELECT sid, sql_id, p1 "file#", p2 "block#", p3 "class#" FROM v$session WHERE event = 'read by other session',观察结果是否高度集中(比如 80% 以上都落在file#=5,block#=123456) - 若分散:大概率是多个不同 SQL 同时全表扫描,问题在 SQL 分布或缺失谓词;若集中:基本锁定为某张表/索引的物理块争用
- 注意:
p2是逻辑块号(block#),不是字节偏移,不能直接用它算文件位置,必须进dba_extents查段
用p1/p2反查dba_extents确认争用对象
file# 和 block# 是唯一可信线索,但别用 dba_objects.object_id 直接关联——X$BH.obj 对应的是 data_object_id,错用会查到错误对象。
- 安全写法:
SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = &FILE_ID AND &BLOCK_ID BETWEEN block_id AND block_id + blocks - 1 - 如果返回为空:该块可能属于系统段(undo、temp)、已 drop 未清理的对象,或存在坏块,需进一步查
v$database_block_corruption - 若多个会话同时卡在同一个
segment_name(如ORDERS_IDX),优先检查这个索引是否被高频扫描(比如状态字段严重倾斜的 B-Tree 索引)
用dbms_xplan.display_cursor看真实执行路径
90% 的 read by other session 根源是执行计划错误,尤其是统计信息过期导致优化器误选全表扫描或低效索引访问路径。
- 执行
SELECT * FROM TABLE(dbms_xplan.display_cursor('&sql_id', NULL, 'ALLSTATS LAST')),重点看STARTS和Buffers列:如果TABLE ACCESS FULL的STARTS=100且Buffers远超预期,说明同一 SQL 被并发执行多次,反复读同一张大表 - 对比 AWR 中历史
PLAN_HASH_VALUE:若当前值与过去稳定值不一致,说明计划已漂移,不是 SQL 本身问题,而是统计信息或绑定变量窥探引发 - 特别注意分区表:常见坑是某分区(如
part_202504)统计信息仍为 0 行,但实际已有数十万数据,DBMS_STATS.GATHER_TABLE_STATS必须显式指定partname参数重收集
区分db file scattered/sequential read类型再定策略
read by other session 总伴随 db file scattered read(多块预读)或 db file sequential read(单块读),但优化方向完全不同。
- 若主要伴随
db file scattered read:说明是全表扫描或索引快速全扫描(INDEX FAST FULL SCAN)触发的预读冲突 → 检查是否缺失谓词、是否应加索引、是否能改用更精准的访问路径 - 若主要伴随
db file sequential read:更可能是索引唯一扫描(INDEX UNIQUE SCAN)或回表时卡在热点索引块(如主键索引根块、小表唯一数据块)→ 考虑增大INITRANS、调小PCTFREE减少 ITL 争用,或对高频访问小表启用缓存(CACHE) - RAC 环境下同步检查
gc buffer busy acquire是否飙升:若同步升高,说明是跨节点争用同一块,需评估缓存融合策略或考虑哈希分区打散物理分布
真正难处理的不是单次等待,而是“同一块被反复争抢”——这背后往往藏着一个没被业务感知的定时任务(比如每30分钟跑一次、却要执行10小时的 JOB),或者一个在小数据量时无感、但随着增长彻底失控的无条件全表扫描。盯住 file#/block# 和 sql_id 的组合,比看任何汇总指标都管用。


















