Direct Path Read在AWR中排第一并非磁盘慢信号,而是SQL绕过Buffer Cache的明确标志;90%以上源于大表全表扫描、排序/Hash Join溢出临时表、并行查询启用,须结合ASH报告定位真实SQL及读取对象,优化目标是合理分流而非消除。

Direct Path Read在AWR里排第一,先别调存储
它不是磁盘慢的信号,而是SQL执行路径绕过Buffer Cache的明确标志。AWR中direct path read等待时间高,90%以上指向三类问题:大表全表扫描、排序/Hash Join溢出到临时表、并行查询启用。直接去查IO吞吐或换SSD,大概率白忙。
从Top 5 Events定位到具体SQL,必须交叉验证ASH
AWR的Top 5 Timed Foreground Events只告诉你“谁在等”,不告诉你“谁在触发”。关键动作是:用AWR里出现的direct path read时间段,立刻生成对应窗口的ASH报告(@?/rdbms/admin/ashrpt.sql),再查Top SQL by Executions或Top SQL by Physical Reads。常见陷阱:
- AWR捕获的
sql_id可能已老化(v$sql被刷出),但ASH里sql_id仍可关联到真实执行 - 并行查询中,
direct path read由PX从属进程产生,父会话显示的是PX Deq: Execute Reply,别误判为网络或队列问题 - 如果ASH里
event列同时出现direct path read和direct path write temp,基本锁定是ORDER BY/GROUP BY导致PGA不足、被迫写临时表
查清读的是什么对象:文件号+块号→表名+段类型
AWR不会直接告诉你读的是哪张表。得靠P1(file#)和P2(first block#)反查:dba_data_files定位文件名,再结合dba_extents找归属段。典型操作链:
- 从
dba_hist_active_sess_history中提取event = 'direct path read'且sql_id = 'xxx'的记录,取p1, p2, p3 - 执行:
SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = &p1 AND &p2 BETWEEN block_id AND block_id + blocks - 1 - 若结果
segment_type是SORT或HASH,说明是内存不足引发的临时段读;若是TABLE或INDEX,重点查该对象是否被频繁全扫
判断是否真需优化:看physical reads direct与physical reads比值
单纯direct path read等待长,不等于有问题。要结合Load Profile里的两个指标:
-
Physical reads direct飙升,但Physical reads没变 → 是并行查询或大排序,属于设计行为,未必是缺陷 -
Physical reads direct和Physical reads同步暴涨 → 真实物理IO压力,需查SQL是否缺失索引、统计信息陈旧、或表膨胀未清理 - 查阈值是否被触发:
SELECT ksppstvl FROM x$ksppi a, x$ksppcv b WHERE a.indx = b.indx AND ksppinm = '_small_table_threshold',若表大小刚超该值,可能是预期行为而非异常
最易忽略的一点:direct path read本身不缓存数据,但它的存在会让Buffer Cache更“干净”——因为大扫描不污染缓存。所以看到它升高,反而要确认小查询的db file sequential read是否因此变得更稳定。优化目标从来不是消灭它,而是让该走它的走,不该走的别走。











