想關注我嗎?請點選圖檔上方

藍字小麥苗關注即可,關注後您将可以每日獲得最實用的資料庫技術。請将小麥苗公衆号置頂,小麥苗不喜歡被壓着,~O(∩_∩)O~
榮
作者小麥苗的今日寄語
多
隻有經曆了紅塵中的善惡是非,愛恨恩仇,才能領悟真正的大道真谛,把人生悟透,将人世看懂,是學道必須的一步。天地間,道大,人也大。人生本來就是,上山,下山。而道心原本寬廣,可容萬物,裝得下山河大地,萬古星辰。
---- 摘自《道士下山》
各位粉絲朋友,從8月13日開始,小麥苗打算花很長很長的一段時間來給大家分享有關自己整理的等待事件的學習筆記,有的内容來自于網絡,大家有什麼問題可以留言,歡迎交流。
今天給大家分享的是等待事件中的User I/O 類等待事件之db file sequential read(資料檔案順序讀)
dbfile sequential read這個等待事件在實際生産庫非常常見,是個與UserI/O相關的等待事件,通常顯示與單個資料塊相關的讀取操作,在大多數情況下,讀取一個索引塊或者通過索引讀取一個資料塊時,都會記錄這個等待。當Oracle需要每次I/O隻讀取單個資料塊這樣的操作時,會産生這個等待事件。最常見的情況有索引的通路(除IFFS外的方式),復原操作,以ROWID的方式通路表中的資料,重建控制檔案,對檔案頭做DUMP等。
在V$SESSION_WAIT這個視圖裡面,這個等待事件有三個參數P1、P2、P3,其中P1代表Oracle要讀取的檔案的絕對檔案号即File#,P2代表Oracle從這個檔案中開始讀取的起始資料塊的BLOCK号即Block#,P3代表Oracle從這個檔案開始讀取的BLOCK号後讀取的BLOCK數量即Blocks,通常這個值為1,表明是單個BLOCK被讀取,如果這個值大于1,則是讀取了多個BLOCK,這種多BLOCK讀取常常出現在早期的Oracle版本中從臨時段中讀取資料的時候。
這個等待事件有三個參數:
File#: 要讀取的資料塊所在資料檔案的檔案号。
Block#: 要讀取的起始資料塊号。
Blocks:要讀取的資料塊數目(這裡應該等于1)。
SELECT*
FROMv$event_name
WHERENAME='db file sequential read';
在Oracle 10g中,這個等待事件被歸入User I/O一類:
這一事件通常顯示與單個資料塊相關的讀取操作(如索引讀取)。如果這個等待事件比較顯著,可能表示在多表連接配接中,表的連接配接順序存在問題,可能沒有正确的使用驅動表;或者可能索引的使用存在問題,不加選擇地進行索引,并非索引總是最好的選擇。
這裡的sequential也并非指的是Oracle按順序的方式來通路資料,和db file scattered read一樣,它指的是讀取的資料塊在記憶體中是以連續的方式存放的。
在大多數的情況下讀取一個索引資料的BLOCK或者通過索引讀取資料的一個BLOCK的時候都會去要讀取相應的資料檔案頭的BLOCK。在早期的版本中會從磁盤中的排序段讀取多個BLOCK到高速緩存區的連續的緩存中。
在大多數情況下,通過索引可以更為快速地擷取記錄,是以對于一個編碼規範、調整良好的資料庫,這個等待事件很大通常是正常的。有時候這個等待過高和存儲分布不連續、連續資料塊中部分被緩存有關,特别對于DML頻繁的資料表,資料以及存儲空間的不連續可能導緻過量的單塊讀,定期的資料整理和空間回收有時候是必須的。但是在很多情況下,使用索引并不是最佳的選擇,比如讀取較大表中大量的資料,全表掃描可能會明顯快于索引掃描,是以在開發中就應該注意,對于這樣的查詢應該避免使用索引掃描。
如果這個等待事件在整個等待時間中占主要的部分,可以采用以下的幾種方法來調整資料庫。
方法一:從AWR的報告中的"SQL ordered by Reads"部分或者從V$SQL視圖中找出讀取實體磁盤I/O最多的幾個SQL語句,優化這些SQL語句以減少對I/O的讀取需求。
如果有Index Range scans,但是卻使用了不該用的索引,就會導緻通路更多的BLOCK,這個時候應該強迫使用一個可選擇的索引,使通路同樣的資料盡可能的少的通路索引塊,減少實體I/O的讀取;如果索引的碎片比較多,那麼每個BLOCK存儲的索引資料就比較少,這樣需要通路的BLOCK就多,這個時候一般來說最好把索引rebuild,減少索引的碎片;如果被使用的索引存在一個很大的Clustering Factor,那麼對于每個索引BLOCK擷取相應的記錄的時候就要通路更多表的BLOCK,這個時候可以使用特殊的索引列排序來重建表的所有記錄,這樣可以大大的減少Clustering Factor,例如:一個表有A,B,C,D,E五個列,索引建立在A,C上,這樣可以使用如下語句來重建表:
CREATE TABLE TABLE_NAME AS SELECT * FROM old ORDER BY A,C;
此外,還可以通過使用分區索引來減少索引BLOCK和表BLOCK的讀取。
方法二:如果不存在有問題的執行計劃導緻讀取過多的實體I/O的特殊SQL語句,那麼可能存在以下的情況:
資料檔案所在的磁盤存在大量的活動,導緻其I/O性能很差。這種情況下可以通過檢視AWR報告中的"File I/O Statistics"部分或者V$FILESTAT視圖找出熱點的磁盤,然後将在這些磁盤上的資料檔案移動到那些使用了條帶集、RAID等能實作I/O負載均衡的磁盤上去。
使用如下的查詢語句可以得到各個資料檔案的I/O分布:
SELECTd.nameNAME,
f.phyrds,
f.phyblkrd,
f.phywrts,
f.phyblkwrt,
f.readtim,
f.writetim
FROMv$filestat f,
v$datafile d
WHEREf.file#=d.file#
ORDERBYf.phyrdsDESC,
f.phywrtsDESC;
從Oracle9.2.0開始,我們可以從V$SEGMENT_STATISTICS視圖中找出實體讀取最多的索引段或者是表段,通過檢視這些資料,可以清楚詳細的看到這些段是否可以使用重建或者分區的方法來減少所使用的I/O。如果Statpack設定的level為7就會在報告中産生"Segment Statistics"的資訊。
SELECTstatistic_name,
COUNT(1)
FROMv$segment_statistics T
GROUPBYT.STATISTIC_NAME;
從上面的查詢可以看到相應的統計名稱,使用下面的查詢語句就能得到讀取實體I/O最多的段:
SELECTobject_name,
object_type,
statistic_name,
VALUE
FROMv$segment_statistics
WHEREstatistic_name='physical reads'
ORDERBYVALUEDESC;
方法三:如果不存在有問題的執行計劃導緻讀取過多的實體I/O的特殊SQL語句,磁盤的I/O也分布的很均勻,這種時候我們可以考慮增大的高速緩存區。對于Oracle8i來說增大初始化參數DB_BLOCK_BUFFERS,讓Statpack中的Buffer Cache的命中率達到一個滿意值;對于Oracle9i來說則可以使用Buffer Cache Advisory工具來調整Buffer Cache;對于熱點的段可以使用多緩沖池,将熱點的索引和表放入到KEEP Buffer Pool中去,盡量讓其在緩沖中被讀取,減少I/O。