[Oracle] 性能調優實例 - read by other session

這幾天每天下午3點開始,開發人員反應Oracle慢,第一等待事件是read by other session

Top 5 Timed Foreground Events

Event Waits Time(s) Avg wait (ms) % DB time Wait Class
read by other session 4,914,569 9,987 2 45.17 User I/O
db file sequential read 3,176,031 7,473 2 33.80 User I/O
DB CPU   2,128   9.62  
db file scattered read 4,104,747 721 0 3.26 User I/O
db file parallel read 10,590 693 65 3.13 User I/O

read by other session 的定義如下:

read by other session Definition: When information is requested from the database, Oracle will first read the data from disk into the database buffer cache. If two or more sessions request the same information, the first session will read the data into the buffer cache while other sessions wait.
In previous versions this wait was classified under the “buffer busy waits” event.
However, in Oracle 10.1 and higher this wait time is now broken out into the “read by other session” wait event. Excessive waits for this event are typically due to several processes repeatedly reading the same blocks, e.g. many sessions scanning the same index or performing full-table scans on the same table. Tuning this issue is a matter of finding and eliminating this contention.
Confio concludes with a summary that “read by other session waits” are very similar to buffer busy waits
When a session waits on the “read by other session” event, it indicates a wait for another session to read the data from disk into the Oracle buffer cache.
If this happens too often the performance of the query or the entire database can suffer. Typically this is caused by contention for “hot” blocks or objects so it is imperative to find out which data is being contended for. Once that is known this document lists several alternative methods for solving the issue.
總結:兩個或者多個會話同時需要把硬盤中的對象裝載到data buffer中,當其中一個會話把對象裝入後,其他會話就處於read by other session等待狀態;這個是oracle 10g 從oracle 9i的buffer busy waits中分離出來的,也是需要一種熱塊現象
從上面的解釋可以知道,read by other session如果伴隨着db file sequential read出現,通常表示有索引熱塊。

導致索引熱塊的SQL如下:

 select count(*) from p95169.order_info o 
 where o.proxyuseruuid =:1 and proxyuseruuid is not null and proxyuseruuid <> 0
 and o.ORDERSTATE in ( 0, 1, 3, 2008, 2009, 3008, 3009, 5002, 5003, 5004, 5006, 7001, 7003, 7002, 7004, 7006 ) 
 and o.ORDERCREATEDTIME >= to_char(sysdate - 15 , 'yyyyMMddHH24mmss') and o.ORDERCREATEDTIME <= to_char(sysdate , 'yyyyMMddHH24mmss') 
 and o.confirmstate in ( 1 ) and o.paystate in ( 1, 0 ) 
 and o.CLINICALDATE <= to_char(sysdate, 'yyyyMMDD') and o.sourceplatid in ( 20 )

通過分析執行計劃,可知它走的是以下索引:

CREATE INDEX "P95169"."IDX_ORDER_HOS_STAT_CLINICAL" ON "P95169"."ORDER_INFO" 
("CLINICALDATE" DESC, "ORDERSTATE", "HOSPITALUUID", "ORDERUUID", 
"RESERVETIMERANGE", "PATIENTNAME", "CONFIRMSTATE", "SOURCEPLATID", "SEEFLAG")
根據索引的前綴性原則,我們可以知道,上訴索引真正用的的字段是前兩列,而前兩列在where字句裏的過濾條件是固定不變的,如果同時又多個這樣的SQL在執行,就會引起索引熱塊,即產生read by other session
通過觀察可知,該SQL語句where字句裏變化的字段是proxyuseruuid,因此重建一個索引,包含該字段,就可以避免索引熱塊:

CREATE INDEX "P95169"."ORDER_INFO_PROXY" ON "P95169"."ORDER_INFO" ("PROXYUSERUUID", "CLINICALDATE", "ORDERCREATEDTIME")

至此,問題解決。

參考文檔:http://www.xifenfei.com/1200.html

發佈了203 篇原創文章 · 獲贊 26 · 訪問量 94萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章