db file scattered read等待事件有3個(gè)參數(shù):file#,first block#,和block數(shù)量.
在處理有關(guān)db file scattered read等待事件的時(shí)候牢記以下關(guān)鍵想法:
1.oracle會話已經(jīng)請求并且正等待從磁盤把多個(gè)鄰近的數(shù)據(jù)庫塊(可達(dá)db_file_multiblock_read_count數(shù)量)讀入到SGA,。
2.多塊I/O請求和全表掃描(full table scans),索引快速掃描(index fast full scans)操作有關(guān)
3.看單獨(dú)會話的兩個(gè)重要的數(shù)字,,TIME_WAITED和AVERAGE_WAIT
4.重要的db file scattered read是最可能是一個(gè)應(yīng)用問題
db file scattered read等待事件很像db file sequential read事件,。但不是單塊讀,這是多塊讀,。db file scattered read等待事件發(fā)起者是執(zhí)行對表和索引全掃描操作操作的SQL語句(用戶和遞歸兩者),。
你能最小化db file scattered read等待的方法和對db file sequential read一樣。
l 優(yōu)化導(dǎo)致更多等待的SQL語句,。目標(biāo)是最小化物理和邏輯讀的數(shù)量
l 降低平均等待時(shí)間
在9I之前,,為SQL語句生成精確的解釋計(jì)劃是一個(gè)辛苦的任務(wù),特別如果你的模式?jīng)]有特權(quán)通過SQL語句訪問對象,。但是,,任務(wù)現(xiàn)在是輕快的,9I開始有了v$sql_plan視圖,。以下查詢提取了當(dāng)前執(zhí)行全表掃描的SQL語句的執(zhí)行計(jì)劃:
set linesize 132
break on hash_value skip 1 dup
col child_number format 9999 heading 'CHILD'
col operation format a55
col cost format 99999
col kbytes format 999999
col object format a25
select hash_value,
child_number,
lpad(' ',2*depth)||operation||' '||options||decode(id, 0, substr(optimizer,1,
6)||' Cost='||to_char(cost)) operation,
object_name object,
cost,
cardinality,
round(bytes / 1024) kbytes
from v$sql_plan
where hash_value in (select a.sql_hash_value
from v$session a, v$session_wait b
where a.sid = b.sid
and b.event = 'db file scattered read')
order by hash_value, child_number, id;
如果應(yīng)用已經(jīng)運(yùn)行了一段時(shí)間,,突然計(jì)時(shí)許多時(shí)間在db file scattered read事件,并且沒有任何代碼的變動,,你可以嘗試去檢查看是否一個(gè)或多個(gè)索引已經(jīng)被drop或變?yōu)?/span>unusable了,。為了判斷哪一個(gè)索引已經(jīng)被drop了,你能比較開發(fā),,測試和生長庫,。你也可以檢查當(dāng)DBA_OBJECTS視圖中的LAST_DDL_TIME。當(dāng)索引被創(chuàng)建的時(shí)候,,oracle在LAST_DDL_TIME字段上貼上日期和時(shí)間,。ALTER TABLE MOVE命令標(biāo)志所有相關(guān)的索引為unusable。某些分區(qū)操作也導(dǎo)致索引被標(biāo)志為unusable,。這包括在hash分區(qū)表中增加一個(gè)新分區(qū)或合并分區(qū),;從一個(gè)分區(qū)表或全局分區(qū)索引中drop一個(gè)分區(qū);修改分區(qū)屬性,;合并,,移動,或truncate表分區(qū),。一個(gè)direct load操作的失敗,,也會讓索引們變?yōu)?/span>unusable狀態(tài),。通過重建索引是很容易處理的。
初始化參數(shù),,當(dāng)增加值的時(shí)候,,能讓優(yōu)化器曲解全掃描:
DB_FILE_MULTIBLOCK_READ_COUNT(MBRC),HASH_AREA_SIZE和OPTIMIZER_INDEX_COST_ADJ,。查明會話正運(yùn)行使用的值,,做合適的調(diào)整,讓他們不會反向影響應(yīng)用的運(yùn)行時(shí)間,。
然而,,另一個(gè)因素也會影響執(zhí)行計(jì)劃的品質(zhì),導(dǎo)致額外的I/O,,它就是有不準(zhǔn)確的統(tǒng)計(jì)信息,。
為什么db file sequential read事件在full table scan操作中顯現(xiàn)
--也就是問:在多塊讀中為什么會有單塊讀存在
l extent的大小 當(dāng)擴(kuò)展區(qū)中的最后一組塊僅是1個(gè)塊,oracle使用單塊讀來提取這個(gè)塊,。這正常來說不是一個(gè)問題,,除非你擴(kuò)展區(qū)尺寸太小。以下是一個(gè)event 10046的trace文件,,顯示在全表掃描操作中包圍的db file sequential read事件,。表塊尺寸是8K,MBRC是8個(gè)塊,,擴(kuò)展區(qū)尺寸是72K(9個(gè)塊),。如果表是大的,對表的全表掃描將導(dǎo)致許多db file sequential read事件,。如果是這種情況,,全表掃描操作將完成的較快,如果表以一個(gè)較大的擴(kuò)展區(qū)尺寸重建的話,。
l cached block 在multiblock讀的一組中的1個(gè)或多個(gè)塊已經(jīng)在buffer cache中了,,因此oracle把fetch分割成2個(gè)或多個(gè)讀,它可以有單塊或多塊I/O組成,。例如,,如果MBRC是8,塊3和塊7是在buffer cache中,,oracle將提出3個(gè)讀呼叫――第一個(gè)是塊1和塊2,第二個(gè)是塊4 和塊6,,第三個(gè)是塊8,。因此第三個(gè)fetch是單數(shù)據(jù)塊,等待事件就是db file sequential read,。然而,,對于前2個(gè)讀呼叫,,這等待事件是db file scattered read,因?yàn)閴K的數(shù)量是超過1的,。因此,,被緩存的塊能導(dǎo)致全表掃描操作來執(zhí)行比所需更多的讀。
l chained or migrated rows 這就是一個(gè)問題,,當(dāng)sql語句的執(zhí)行計(jì)劃請求一個(gè)全表掃描的時(shí)候,,如果你看到很多對該表的db file sequential read等待。這象征了表有許多鏈接或移植的行,。Oracle使用單塊讀i/o來訪問每一個(gè)鏈接的或移植的行,。檢查在DBA_TABLES視圖中的表的CHAIN_CNT。當(dāng)然,,CHAIN_CNT是LAST_ANALYZED日期開始的,。被移植的行能通過重組表來糾正(譬如export和import,或alter table move),。
l index entry creation 它不是一個(gè)問題,,當(dāng)你在sql語句執(zhí)行計(jì)劃呼叫一個(gè)全表掃描的時(shí)候,如果你看見許多針對index的db file sequential read等待,。在以下例子中,,TABLE_A有一個(gè)索引,db file sequential read等待是讀index塊到SGA來充滿來自TABLE_B數(shù)據(jù)的結(jié)果,。注意db file sequential read等待與db file scattered read統(tǒng)計(jì)數(shù)據(jù)上比較的數(shù)量,。這暗示你不能再假設(shè)你將從執(zhí)行計(jì)劃上就能看到是哪個(gè)瓶頸。許多DBAs希望看到許多db file scattered read事件,。另一個(gè)一文不值的觀點(diǎn)就是db file sequential read等待事件不會應(yīng)用于insert語句,。一般的誤解就是它僅應(yīng)用到update和delete語句。