这种情况通常显示与全表扫描相关的等待。
当数据库进行全表扫时,基于性能的考虑,数据会分散(scattered)读入Buffer Cache。如果这个等待事件比较显著,
可能说明对于某些全表扫描的表,没有创建索引或者没有创建合适的索引,我们可能需要检查这些数据表已确定是否进
行了正确的设置。 然而这个等待事件不一定意味着性能低下,在某些条件下Oracle会主动使用全表扫描来替换索引扫描以提高性能,这
和访问的数据量有关,在CBO下Oracle会进行更为智能的选择,在RBO下Oracle更倾向于使用索引。 因为全表扫描被置于LRU(Least Recently Used,最近最少适用)列表的冷端(cold end),对于频繁访问的较
小的数据表,可以选择把他们Cache到内存中,以避免反复读取。 当这个等待事件比较显著时,可以结合v$session_longops动态性能视图来进行诊断,该视图中记录了长时间(运
行时间超过6秒的)运行的事物,可能很多是全表扫描操作(不管怎样,这部分信息都是值得我们注意的)。 我们通过通过一个案例分析来熟悉一下这个等待事件:
DB Name DB Id Instance Inst Num Release OPS Host ---------- ----------- ---------- -------- ---------- ---- ---------- K2 1999167370 k2 1 8.1.5.0.0 NO k2 这是一个8.1.5的数据库系统,通过脚本增强,我们可以在8.1.5的数据库上使用statspack来进行数据库诊断。 Snap Length Start Id End Id Start Time End Time (Minutes) -------- -------- -------------------- -------------------- ----------- 170 176 25-Feb-03 10:00:11 25-Feb-03 15:00:05 299.90 Cache Sizes ~~~~~~~~~~~ db_block_buffers: 64000 db_block_size: 8192 log_buffer: 8388608 shared_pool_size: 157286400 ……………… Top 5 Wait Events ~~~~~~~~~~~~~~~~~ Wait % TotalEvent Waits Time (cs) Wt Time-------------------------------------------- ------------ ----------------------- -------db file scattered read 16,842,920 3,490,719 43.32latch free 844,272 3,270,073 40.58buffer busy waits 114,421 933,136 11.58db file sequential read 2,067,910 117,750 1.46enqueue 464 110,840 1.38 ------------------------------------------------------------- 这是一个典型的性能低下的系统,几个重要的等待事件都在Top 5中出现,其中,前3个等待极为显著,需要进行相应的调整。在5小时的采样间隔内,其中db file scattered read累计等待时间约10小时,已经成为影响系统性能的主要原因。了解了这些以后我们就可以进一步察看相关SQL看是否存在可以的SQL语句。SQL ordered by Gets for DB: K2 Instance: k2 Snaps: 170 - 176 Gets % of Buffer Gets Executes per Exec Total Hash Value -------------- ------------ ------------ ------ ------------ SQL statement ------------------------------------------------------------------------------ 6,480,163 12 540,013.6 2.4 3791855498 SELECT "PROCESS_REQ"."WORK_ID", "PROCESS_REQ"."STOCK_NO", "PROCESS_R 3,784,566 16 236,535.4 1.4 2932917818 SELECT * FROM FIND_LATER_WO ORDER BY NOTE,ORDER_NO 1,200,976 3 400,325.3 .4 4122791109 SELECT "ITEM_STOCK"."ITEM_NO", "ITEM"."NOTE", "ITEM" 923,944 9 102,660.4 .3 2200071737 SELECT "ITEM_STOCK"."ITEM_NO" , "ITEM_STOCK"."STOCK_NO" , 921,301 3 307,100.3 .3 2218843294 SELECT "ITEM_STOCK"."ITEM_NO", "ITEM"."NOTE", "ITEM" 911,285 3 303,761.7 .3 1769130587 SELECT "LISTS"."ITEM_NO" , "LISTS"."SUB_ITEM" , "LISTS" 831,439 2 415,719.5 .3 1349577999 SELECT "GROUP_OPER"."ITEM_NO" , "GROUP_OPER"."PROCESS_ID" , 802,918 1 802,918.0 .3 3613809507 SELECT "LISTS"."ITEM_NO" , "LISTS"."SUB_ITEM" , "ITEM". 800,548 2 400,274.0 .3 2643788247 SELECT "ITEM_STOCK"."ITEM_NO", "ITEM"."NOTE", "ITEM" 666,085 2 333,042.5 .2 3391363608 SELECT "ITEM_STOCK"."ITEM_NO", "ITEM_STOCK"."STOCK_NO", ……….. 注意到以上很多查询导致的Buffer Gets都非常庞大,我们非常有理由怀疑索引存在问题,甚至缺少必要的索引。以上记录的是SQL的片段,通过Hash Value值结合v$sql_text我们可以获得完整的SQL语句。在这次诊断中,我紧接着去查询的是v$session_longops数据表,一个分组查询的结果如下:TARGET COUNT(*)---------------------------------------------------------------- ----------SA.PPBT_GRAPHOBJTABLE 418SA.PPBT_PPBTOBJRELATTABLE 53我们发现这些问题SQL的全表扫描(结合v$session_longops视图中的OPNAME)主要集中在PPBT_GRAPHOBJTABLE和PPBT_PPBTOBJRELATTABLE两张数据表上。进一步研究发现这两个数据表上没有任何索引,并且有相当的数据量:SQL> select count(*) from SA.PPBT_PPBTOBJRELATTABLE; COUNT(*)---------- 1209017 SQL> select count(*) from SA.PPBT_GRAPHOBJTABLE; COUNT(*)---------- 2445在创建了合适的索引后,系统性能得到了大幅提高! |
|