direct path read /write(直接路径读/写)

时间:2021-09-12 19:51:02

参考自盖国强《深入解析oracle》

直接路径读(direct path read)通常发生在 Oracle 直接读数据到进程 PGA 时,这个读取不需要经过 SGA。
这类读取通常在以下情况被使用:
	磁盘排序 IO 操作;
	并行查询从属进程;
	预读操作;
	串行全表扫描(Oracle 11g 新特性)
直接路径写(direct path write)通常发生在 Oracle 直接从 PGA 写数据到数据文件或临时文件,这个写操作可以绕过 SGA。
这类写入操作通常在以下情况被使用:
	直接路径加载;
	并行 DML 操作;
	磁盘排序;
	对未缓存的“LOB”段的写入,随后会记录为 direct path write (lob)等待。
最为常见的直接路径写,多数因为磁盘排序导致。对于这一写入等待,我们应该找到 I/O操作最为频繁的数据文件(如果有过多的排序操作,很有可能就是临时文件),分散负载,加快其写入操作。
	1.磁盘排序诊断
如果系统存在过多的磁盘排序,会导致临时表空间操作频繁,对于这种情况,可以考虑为不同用户分配不同的临时表空间,使用多个临时文件,写入不同磁盘或者裸设备,从而降低竞争,提高性能。对于显著的磁盘排序,可以很容易地猜测到,临时表空间的读写操作肯定相当频繁,可以适当增大 pga_aggregate_target,以缩减磁盘排序对于硬盘的写入,从而提高系统及应用相应。但是通常应该及时检查应用,确认是否因为应用问题而导致了过度排序,从而从根本上解决问题。
	2.并行查询性能问题
在很多情况下,并行也许并不是最好的选择,如果表并不大,并行反而会降低其执行速度。
数据库的内存排序率是 100%(In-memory Sort %: 100.00),显然这里的 Direct Path Read 并不是由于排序引发的,注意到另外一个等待事件(KJC: Wait for msg sends to complete)和并行有关,所以初步判断这里的 direct path read 可能和并行有关。
查看涉及数据表的并行度:
SQL> select table_name,degree from dba_tables where table_name='WORKER';

TABLE_NAME                     DEGREE
------------------------------ --------------------
WORKER                                  1
将表的并行度修改为 1:
SQL> alter table test.worker parallel 1;

Table altered.
	3.磁盘排序与临时文件
direct path read/write temp 就是单指对于临时文件的直接读写操作,为了分离临时文件号和数据文件号,Oracle 对临时文件的编
号以 db_files 为起点,所以临时文件的绝对文件号应该等于 db_files + file#。
	4.串行全表扫描 – Serial Table Scan
在 Oracle Database 11g 中,一种被称为 串行全表扫描(Serial Table Scan)的技术被引入,该特性根据数据块的设置和统计信息等,自动决定是采用 Direct Path Read 绕过 SGA,还是采用常规方式读取,因为这种自动选择,这一特性又被称为 自适应直接读(Adaptive Direct Read) .
串行表扫描以物理读方式执行,每次执行该查询,产生同样的物理读.
使用串行全表扫描和多个因素有关,首先全表访问的数据表需要至少超过 5 倍的_small_table_threshold 设置,因为通常小表的全表访问并不会对 Buffer Cache 产生过大的冲击.这个隐含参数的缺省值如下:
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
  2  FROM SYS.x$ksppi x, SYS.x$ksppcv y
  3  WHERE x.indx = y.indx AND x.ksppinm LIKE '%&par%';
Enter value for par: _small_table_threshold
old   3: WHERE x.indx = y.indx AND x.ksppinm LIKE '%&par%'
new   3: WHERE x.indx = y.indx AND x.ksppinm LIKE '%_small_table_threshold%'

NAME
--------------------------------------------------------------------------------
VALUE
--------------------------------------------------------------------------------
DESCRIB
--------------------------------------------------------------------------------
_small_table_threshold
1023
lower threshold level of table size for direct reads
Oracle支持通过 10949 事件禁用串行全表扫描(但是当表大于 5 倍的 Buffer Cache 时,则不允许禁用,只能采用直接路径读).
10949 事件可以禁用串行表扫描,而另外一个隐含参数_serial_direct_read 则用于启用串行直接路径读.
通过前面的测试可以看到串行表扫描可以提升全表扫描的性能,但是并非总是如此,尤其是当数据可以 Cache 在内存中被反复访问时,无疑 Scattered Read 更有优势,频繁的物理访问对于 IO 密集系统无疑将是灾难,所以这一技术需要在具体环境中根据判断去应用.