ORACLE之熱塊優化方法小結

原文轉自http://www.itpub.net/thread-1713308-1-1.html


訪問頻率非常高的數據塊被稱爲熱塊(Hot Black,當很多用戶同時訪問某個數據塊時,就會導致Lanch爭用。常見的Lanch爭用

A    buffer busy waits

B    cachebuffer  chain


一、如果是cachebuffer  chain  Latch的,要看訪問相同數據塊的會話會太長或這個列表太長


1)如果這個列表太長

原因:

如果一條hash chain比其他hash chain長,它所管理的buffer header更多,那麼發生cache buffers chains latch等待的機率就更大,

辦法:

   針對這個問題,可以通過增加hash bucket的數量進而影響hash chain的數量來達到縮短hash chain的目的.參數_db_block_hash_latches


原理:

   8.0之前,hash buckets的個數等於db block buffers/4。也就是說,平均一個hash bucket上掛4block。當然這只是平均值,很有可能通過hash函數轉換block header的地址後會導致一個bucket上掛很多個block

   8.0以後,oracle改成了hashbuckets=2*db block buffers。主要是爲了降低一個bucket上掛的block的個數,從而減少掃描bucket所花費的時間。所以說,平均是一個bucket上掛0.5block。但是實際上,一個bucket上可能會掛較多的block,而有些bucket上則沒有掛block,這由block的地址決定。所以,增加bucket的個數,就可以增加block平均分佈在bucket上的概率。


注:

   其實在Oracle9i之後,我們基本上不會遇到這個問題了,除非遇到Bug。所以這個是不推薦的,記住,在對Oracle的隱含參數做修改之前一定要諮詢Oracle Support


2)訪問相同數據塊的會話會太長

原因:

   當多個會話重複訪問一個或多個由同一個子chche buffer chains鎖存器保護的塊時,熱塊就產生。

辦法:

   調整隱藏參數_spin_count,增加進程成功獲取latch的可能性,這個方法要慎用,增大_spin_count會增加cpu的負荷從而可能造成負面效果。



二、如果是buffer busy waits

1、、找到熱塊產生的SQL,根據執行計劃查看是否合理,改變SQL爲最優SQL

A、找到最熱的數據塊的latchbuffer信息

select  b.addr,a.ts#,a.dbarfil,a.dbablk,a.tch,b.gets,b.misses,b.sleeps  from  
(select   *   from   (select  addr,ts#,file#,dbarfil,dbablk,tch,hladdr   from  x$bh   order   by   tch  desc)   where   rownum <11)   a,
(select   addr,gets,misses,sleeps   from  v$latch_children   where   name= 'cache  buffers   chains ')   b
where   a.hladdr=b.addr;

B、找到熱點buffer對應的對象信息:

col   owner   for   a20
col   segment_name   for   a30
col   segment_type   for   a30

select   distinct  e.owner,e.segment_name,e.segment_type   from  dba_extents   e,  
(select   *   from   (select  addr,ts#,file#,dbarfil,dbablk,tch   from   x$bh  order   by   tch   desc)  where   rownum <11)   b
where   e.relative_fno=b.dbarfil
and   e.block_id <=b.dbablk
and   e.block_id+e.blocks> b.dbablk;

C、找到操作這些熱點對象的sql語句:

break   on   hash_value   skip   1
select   /*+rule*/   hash_value,sql_text  from   v$sqltext   where  (hash_value,address)   in  
(select   a.hash_value,a.address   from  v$sqltext   a,(select   distinct  a.owner,a.segment_name,a.segment_type   from  dba_extents   a,
(select   dbarfil,dbablk   from   (select  dbarfil,dbablk   from   x$bh   order  by   tch   desc)   where   rownum<11)   b   where   a.relative_fno=b.dbarfil
and   a.block_id <=b.dbablk   and  a.block_id+a.blocks> b.dbablk)   b
where   a.sql_text   like   '%'||b.segment_name|| '% '   and   b.segment_type= 'TABLE ')
order   by   hash_value,address,piece;

D.根據執行計劃,調整SQL語句。比如的表的連接方式,訪問路徑等。


2、加大表或者索引的PCTFREE,使每個數據塊中存放更少的行調整PCTFREE時,參數雖然是可以動態調整的,但是隻能對新的數據插入起作用,對於已經填充過滿的老數據塊,是無法起作用的,必須調整參數後,對錶進行重組,才能對錶中的所有數據塊都起作用。表中的行分佈在更多的數據塊上,導致Oracle需要讀取更多的數據塊來完成查詢,大大降低了一個數據塊被重複讀取的概率。降低了數據的性能。


3、減小表空間BLOCK SIZE,使每個數據塊中存放更少的行如果減小表空間BLOCK SIZE,可能會造成行鏈接,也可能造成性能上影響。


4、使用hash 簇表和使用HASH 分區表,使數據分佈更爲分散.


5、降低程序的併發度,如果程序中使用了parallel查詢,降低parallel degree,以免多個parallel slave同時訪問同樣的數據對象而形成等待降低性能。


6、把經常操作的小表寫入內存。


7、增加hot block上的initrans值。但注意不要把initrans值設置的過於高了,通常設置爲5就足夠了。因爲增加事務意味着要增加ITL事務槽,而每個ITL事務槽將佔用數據塊中24個字節長度。默認情況下,每個數據塊或者索引塊中是ITL槽是2個,在增加initrans的時候,可以考慮增大數據塊所在的表的PCTFREE值,這樣Oracle會利用PCTFREE部分的空間增加ITL slot數量,最大達到maxtrans指定。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章