您的位置:首页 > 数据库 > Oracle

Oracle IO问题解析(八)

2012-05-17 14:20 405 查看
3.2.3dbfileparallelread
首先,不要被该事件名称所误导——它和并行DML或者并行查询都无关。当从多个数据文件并行读取数据到非联系的内存(PGA、BufferCache)缓冲中时,会发生该等待事件。它通常发生在Recovery操作或者利用缓冲预提取(BufferPrefetching)从数据文件并行读取数据时。
我们可以通过以下语句找出发生dbfileparallelread等待事件的数据文件和数据块:

selectp1"fileid",p2"block_id",p3"requests"

fromv$session_wait

whereevent='dbfileparallelread';


优化该等待事件的手段可以参考优化dbfilesequentialread等待事件中非SQL优化方法部分。
3.2.4directpathread&directpathread(lob)
当直接读取(DirectRead)数据到PGA(而不是到BufferCache)中去时,会发生DirectPathRead等待事件。对Lob数据的直接读有一个单独的等待事件——directpathread(lob)。
当Oracle设置支持异步IO时,进程可以在提交IO请求后继续做其他操作,并且在稍后再提取IO请求返回的结果,在提取结果时就产生了directpathread等待事件。
在没有启用异步IO时,IO请求在完成之前会被阻塞,但在执行IO操作时并不会产生等待事件。进程稍后回来提取那些已经读取到的IO数据,这时尽管能够很快返回,但仍然会显示directpathread等待事件。
和其他IO等待事件不同的是,对DirectPathRead等待事件要注意以下两点:

等待次数并不等于IO请求次数;

统计(如statspack报告中)得出的DirectPathRead的等待时间并不一定代表该事件引起的真正等待时间。

事件中的P1、P2、P3参数分别代表:
P1:发生等待事件的数据块所在文件号;
P2:发生等待事件的数据块号;
P3:等待事件涉及的连续数据块数量。

直接读(DirectRead)请求一般发生在以下几种情况:

磁盘排序IO(SortArea不足时,排序用到的临时数据会被写到临时表空间上去,当读取这些数据时就使用直接读);

并行查询;

预读取(当一个进程认为某个数据块将很快被用到而发出IO请求时)

HashJoin(HashArea不足)

IO负载系统中,服务进程处理缓存的速度比系统IO返回数据到缓存的速度更快时

通过视图V$SESSION_EVENT我们可以找出当前产生等待的会话,再根据会话中正在进行的操作确定导致等待的原因。针对不同的原因,我们可以采取不同的措施减少DirectPathRead等待事件。
3.2.4.1磁盘排序
首先我们可以考虑优化语句以减少排序操作。排序一般是由以下操作引起的:

oOrderBy;
oJOIN;
oUNION;
oGroupBy;
o聚合操作;
oSelectunique;
oSelectdistinct;

可以尝试在语句中减少没必要的上述操作来避免排序操作。另外,创建索引也会引起排序操作。在专业模式(Dedicated)下,排序所占用的内存是从PGA中分配出来的一块区域,叫SortArea,由参数sort_area_size控制其大小;在MTS中,排序区是从LargePool中分配的。当sortarea大小无法满足排序操作要求时,就会占用临时表空间来存放排序数据,因而产生DirectPathRead等待事件。我们可以通过适当增加该参数来减少磁盘排序操作。
这个参数可以在系统范围或会话范围进行修改。对于一些需要做大量排序操作而且又比较独立的会话(如CreateIndex),我们可以在会话级别为其设置比较大的SortArea以满足排序需要:

SQL>altersessionsetsort_area_size=10000000;


Sessionaltered.


该参数大小一般推荐设置为1~3M。在9i之后,不推荐设置该参数,我们可以通过设置PGA_AGGREGATE_TARGET进行PGA内存自动管理(设置WORKAREA_SIZE_POLICY为TRUE)。对于PGA_AGGREGATE_TARGET的大小设置,可以参考文章《Oracle内存全面分析》中的PGA_AGGREGATE_TARGET部分。
此外,我们还可以通过以下语句来查找系统中存在磁盘排序的会话及其语句:

SELECTa.sid,a.value,b.name,d.sql_textfrom
V$SESSTATa,V$STATNAMEb,V$SESSIONc,V$SQLAREAd
WHEREa.statistic#=b.statistic#
ANDb.name='sorts(disk)'
anda.sid=c.sid
andc.SQL_ADDRESS=d.ADDRESS(+)
andc.SQL_HASH_VALUE=d.HASH_VALUE(+)
andvalue>0
ORDERBY2desc,1;

3.2.4.2并行查询
当设置表的并行度非常高时,优化器可能就对表进行并行全表扫描,这时会引起DirectPathRead等待。
在使用并行查询前需要慎重考虑,因为并行查询尽管能教师程序的响应时间,但是会消耗比较多的资源。对于低配置的数据库服务器不建议使用并行特性。此外,需要确认并行度的设置要与IO系统的配置相符(建议并行度为2~4*CPU数)。在10g中,可以考虑使用ASM。
对于表的并行度,我们不建议直接用ALERT修改表的物理并行度:

ALTERTABLEt_test1PARALLELDEGREE16;


而是推荐针对特定语句使用提示来设置表的并行度:

SQL>SELECT/*+FULL(T)PARALLEL(T,4)*/object_nameFROMt_test1t;


47582rowsselected.



ExecutionPlan

----------------------------------------------------------

Planhashvalue:2467664162


--------------------------------------------------------------------------------

|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time

|TQ|IN-OUT|PQDistrib|

---------------------------------------------------------------------------
-----[/code]
|0|SELECTSTATEMENT||47582|1068K|42(3)|00:00:01

||||

|1|PXCOORDINATOR|||||

||||

|2|PXSENDQC(RANDOM)|:TQ10000|47582|1068K|42(3)|00:00:01

|Q1,00|P->S|QC(RAND)|

|3|PXBLOCKITERATOR||47582|1068K|42(3)|00:00:01

|Q1,00|PCWC||

|4|TABLEACCESSFULL|T_TEST1|47582|1068K|42(3)|00:00:01

|Q1,00|PCWP||

--------------------------------------------------------------------------------

3.2.4.3HashJoin
HashArea是用于hashjoin的内存区域。HashArea过小会引起DirectPathRead等待。当WORKAREA_SIZE_POLICY为FALSE时,可以考虑增加hash_area_size的大小(建议为sort_area_size大小的1.5倍);当WORKAREA_SIZE_POLICY为TRUE时,可以考虑增加PGA_AGGREGATE_TARGET大小。
3.2.4.4Directpathread(lob)
为了减少LOB的读写时间,通常我们会设置LOB的存储参数NOCACHE,这时读取LOB时会引起DirectPathRead(lob)等待事件。但当我们发现Directpathread(lob)引起了IO性能问题,就需要考虑将那些被经常读取的LOB字段设置为CACHE。另外,如果操作系统的文件系统有足够的BufferCache时可以考虑将LOB数据段存储在文件系统上。
3.2.4.5其他优化措施
当内存资源不足、IO读取数据到内存效率远远低于内存中数据被处理的效率时,会引起DirectPathRead等待事件。作为对上述处理措施的补充,增加内存(PGA)、在确保操作系统支持AIO情况下设置DISK_ASYNCH_IO为TRUE以支持异步IO、采用效率更高的存储设备都能帮助我们减少DirectPathRead等待。
3.2.5directpathwrite&directpathwrite(lob)

直接写(DirectPathWrite)允许一个会话先将IO写请求放入一个队列中,让操作系统去处理IO,而自身可以继续处理其他操作。当会话需要知道写操作是否完成(如会话需要一块空闲的缓存块或者会话需要确认内存中所有写操作都被flush到磁盘了),会话就会等待写操作完成从而产生DirectPathWrite等待事件。DirectPathWrite(lob)是在对LOB数据段(NOCACHE)直接写时产生的等待事件。
在没有启用异步IO时,IO写请求在完成之前会被阻塞,但在执行IO写操作时并不会产生等待事件。进程稍后回来提取那些已经完成的IO操作数据,这时尽管能够很快返回,但仍然会显示directpathwrite等待事件。
和DirectPathRead等待事件相似,对DirectPathWrite等待事件也要注意以下两点:

等待次数并不等于IO请求次数;

统计(如statspack报告中)得出的DirectPathWrite的等待时间并不一定代表该事件引起的真正等待时间。

事件中的P1、P2、P3参数分别代表:
P1:发生等待事件的数据块所在文件号;
P2:发生等待事件的数据块号;
P3:等待事件涉及的连续数据块数量。

直接写请求一般发生在以下几种情况:

直接数据载入操作(如CTAS、SQL*Loader设置Direct选项等);

并行DML操作;

磁盘排序(排序内存空间不足,数据写入磁盘);

载入NOCACHE数据段;

对DirectPathWrite的优化处理措施基本上和DirectPathWrite类似。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Oracle 数据 查询