继续完成等待事件系列。
什么是:db file sequential read:?
简单说,就是oracle要读取单块数据,其他会话存在等待,有三个参数p1,是要读的文件,p2是block#,开始读取的数据块号,p3是blocks,一般p3为单块,但是如果是多块那么一般发生在从temporary segment中读的。
该类等待事件的出现主要是由于执行对索引,回滚(undo)段,和表(当借助rowid来访问),控制文件和数据文件头的单块读操作sql语句(用户和递归)引起的,该事件的产生要么表的连接顺序有问题,要么索引使用不当导致。
如何解决呢:
1、优化sql,主要是看执行计划,能不走全表的就不走全表(但是有时候全表可能比索引更快),能走index scan的就不走table access byindex rowid.
2、增加file的i/0速率,一般对于硬件存储设备而言,数据文件所在的磁盘采用哪种raid也是很显著
3、增加buffer cache大小,使其数据在内存中得到,但是到了10g、11g 启用了asmm和amm那么buffer cache是会动的,或者考虑将相关表存放到keep 池中,如果是11g可以考虑result cache。
4、可以将数据放到非标准块中(大块存多行数据),避免i/0
5、采用索引组织表,,减少i/o
6、采用并行查询执行(占用一定内存和cpu,需要依据主机负载判断)
7、可以尝试采用分区表等。
案例分析:
1、获得sql信息如下:
fromwf_deal_common_main_t m,
wfc_root_sub_relation_t r,
rt_workiteminst w
where m.f_procinst_id = r.root_id
and r.sub_id =w.proc_instance_id
查看执行计划如下:
>select count(1)
16:02:35 2 from wf_deal_common_main_t m,
16:02:35 3 wfc_root_sub_relation_t r,
16:02:35 4 rt_workiteminst w
16:02:35 5 where m.f_procinst_id = r.root_id
16:02:35 6 and r.sub_id = w.proc_instance_id
16:02:35 7 and w.current_state in (1, 2)
16:02:36 8 and w.user_id = 999
16:02:36 9 and w.overdued = 1
16:02:36 10 ;
predicate information (identified by operation id):
---------------------------------------------------
4 -filter((w.current_state=1 orw.current_state=2) andw.overdued=1 and
to_number(w.user_id)=999)
6 -access(r.sub_id=w.proc_instance_id)
filter(r.sub_id=w.proc_instance_id)
8 -access(m.f_procinst_id=r.root_id)
note
-----
- dynamic samplingused for this statement
index full scan,table access full。注意此时有隐式转换。
如果把变量换成字符串。执行计划如下:
>r
1 select count(1)
2 from wf_deal_common_main_t m,
3 wfc_root_sub_relation_t r,
4 rt_workiteminst w
5 where m.f_procinst_id = r.root_id
6 and r.sub_id = w.proc_instance_id
7 and w.current_state in (1, 2)
8 and w.user_id ='999'
9* and w.overdued = 2
predicate information (identified by operation id):
---------------------------------------------------
4 -filter((w.current_state=1 orw.current_state=2) andw.overdued=2)
5 -access(w.user_id='640001312')
7 -access(r.sub_id=w.proc_instance_id)
8 -access(m.f_procinst_id=r.root_id)
note
-----
- dynamicsampling used for this statement
总结:
从如上内容,可以分析得出:因为w.user_id为varchar 类型,当w.user_id赋值为数字则会产生index full scan和table access full,这主要是由于隐式转换导致,解决该办法一种是建立函数索引,另一种是在传送该值变量的时候进行转换。建议采用后者。
