direct path read等待高不一定是i/o瓶颈,需先查physical reads direct占比是否超30%及对应sql,再通过segment_type区分是大表扫描还是temp排序/哈希溢出,结合pga_aggregate_target、_small_table_threshold和_serial_direct_read参数综合诊断。

direct path read 等待高,先看是不是真瓶颈
直接判断 direct path read 是不是性能问题根源,不能只看 v$session_event 里的 time_waited。Oracle 对并行从属进程(PX slaves)的等待时间统计不完整,父会话在 PX Deq: Execute Reply 上等,而真正干活的从属进程产生的 direct path read 时间常被低估甚至漏计。
更可靠的做法是查物理读类型分布:
SELECT a.NAME, b.SID, b.VALUE, ROUND((SYSDATE - c.LOGON_TIME) * 24) hours_connected FROM v$statname a, v$sesstat b, v$session c WHERE b.SID = c.SID AND a.STATISTIC# = b.STATISTIC# AND b.VALUE > 0 AND a.NAME = 'physical reads direct' ORDER BY b.VALUE DESC;
如果 physical reads direct 占总物理读(physical reads)比例超过 30%,且集中在少数 SQL 上,才值得深挖。
查清 direct path read 在读什么段
direct path read 本身不区分数据来源,但背后逻辑差异很大:可能是大表全扫、也可能是临时段排序/哈希结果读取。混淆这两类会导致误调优。
用以下语句定位实际读取对象:
SELECT a.event, a.sid, c.sql_id,
DECODE(d.ktssosegt, 1,'SORT', 2,'HASH', 3,'DATA', 4,'INDEX', 5,'LOB_DATA', 6,'LOB_INDEX') AS segment_type,
b.tablespace_name, b.file_name
FROM v$session_wait a, dba_data_files b, v$session c, x$ktsso d
WHERE a.sid = c.sid
AND a.p1 = b.file_id(+)
AND a.p2 = d.ktssofnb(+)
AND a.event = 'direct path read'
AND a.sid IN (SELECT sid FROM v$sesstat WHERE statistic# = 98 AND value > 0);
- 若
segment_type是SORT或HASH,说明是临时表空间(TEMP)读取,根源在内存不足,应调pga_aggregate_target或 SQL 内存操作逻辑 - 若
segment_type是DATA且tablespace_name是用户表空间,说明是大表扫描触发的直接路径读,需检查是否真的需要全表扫描、是否有合适索引、或是否该用并行 -
file_name指向temp01.dbf类文件,基本可确认是direct path read temp场景,和direct path read虽然等待名不同,但诊断路径一致
serial_direct_read 参数影响容易被忽略
Oracle 默认对“小表”走缓存读,大表才走直接路径。但这个阈值受 _small_table_threshold 控制(默认 ≈ 2% 的 db_cache_size),而是否启用直接路径读还受隐含参数 _serial_direct_read 实际取值约束:
-
auto(默认):由优化器根据对象大小和统计信息动态决定 -
always:所有全表扫描都强制走直接路径读 —— 这会让小表也绕过 Buffer Cache,可能反而降低重复访问性能 -
never:完全禁用,所有读都进 Buffer Cache —— 可能导致大表扫描时 Buffer Cache 污染严重
查当前会话实际生效值:
SELECT ksppinm, ksppstvl FROM x$ksppi JOIN x$ksppcv USING (indx) WHERE ksppinm = '_serial_direct_read';
注意:_serial_direct_read 是会话级参数,SQL 中加 /*+ no_parallel */ 不影响它;但加 /*+ parallel(4) */ 会绕过该参数,直接启用并行直接路径读。
别把 direct path read 和 I/O 瓶颈划等号
看到 direct path read 高,第一反应常是“磁盘慢”,但真实瓶颈往往不在 I/O 子系统:
- 如果是
SORT或HASH段读取,本质是 PGA 不足导致溢出到磁盘,调高pga_aggregate_target或改写 SQL 减少排序量,比换 SSD 更有效 - 如果是大表扫描,但执行计划显示
TABLE ACCESS FULL且没有谓词过滤,问题大概率在应用逻辑或缺失索引,而非存储性能 - 并行查询中,
direct path read高常伴随PX Deq: Slave Session Stats或enq: KO - fast object checkpoint,说明协调开销或检查点压力才是根因
真正要确认 I/O 瓶颈,得交叉验证:iostat -x 1 看 %util 和 await,再比对 v$system_event 中 db file scattered read 的平均等待时间 —— 如果后者远高于前者,说明问题不在磁盘,而在 Oracle 层调度或内存分配。











