11g direct path read 等待事件的初步探討

JohnTam10發表於2011-08-05
    這是在做一份某客戶的資料庫效能檢查報告時發現的問題:
top5等待事件中,direct path read的等待佔據第一位,佔db time 的60%,是嚴重的等待。後來通過ASH報告看到進行低效的sql執行時進行的是全表掃描,產生了大量的direct path read等待,在oracle 10g及以前的版本,全表掃描產生的應該是db file scattered read等待,而在11g中,是不是有不同的特性呢?通過檢視資料,我有以下的總結(部分內容經過測試如10949的事件設定):

   
    在11g以前,進行全表掃描,產生的是資料塊的多塊讀,以db file scattered reads等待事件體現,而在11g中,oracle使用了一種新的特性,當進行全表掃描的時候,資料庫會直接從資料檔案中讀資料塊,產生direct path reads等待,使用這種資料讀取方式的判斷依據是根據表的大小,以及當前資料庫設定的buffer cache大小。當buffer cache 過小,而需要快取的表為大表時,資料庫會選擇繞過buffer cache,直接將資料塊讀入PGA中,這樣就避免每次執行SQL時因為表缺少索引而使用全表掃描,引致buffer cache因快取表資料而重新重新整理。
      裡面涉及到許多隱含引數--"_small_table_threshold",它的值衡量了大表和小表的界限。超過這個閥值的被認為是大表。當全表掃描的是小表時並不會使用直接路徑讀。
      另一個隱含引數就是"_very_large_object_threshold" ,它定義了使用直接讀進行全表掃描的表物件的最大值(MB)。如果只是單獨設定這個引數對全秒掃描時選擇資料讀取方式的選擇並不起作用。
      執行direct path read的好處有:當sql進行全表掃描時,如果仍然使用離散讀的方式,則程式需要將儲存中相連的資料塊讀入buffer cache,而這些連續的資料塊中如果已經有部分不連續的塊被快取到cache中,資料庫實際上進行的是對儲存中剩下的資料塊進行一個一個的順序讀,這樣執行效率大大降低,因此選擇直接讀來一次性完成全表掃描需要讀取的資料。另外,正因為不用將資料塊讀入buffer,減少了Cache Buffer Chain 和Cache Buffer LRU Chain 栓鎖競爭,大大降低CPU的使用時間。
    但是使用direct path read同樣有缺點:每次執行全表掃描的時候跳過buffer cache,將資料直接從儲存讀到使用者PGA中,產生比較大的物理IO,造成磁碟IO壓力。另外,在直接讀取某段資料前可能需對該物件進行一次段級檢查點,以防止讀入的是舊的資料塊。
     關於手工禁止直接路徑讀:
     設定10949事件可以令到資料庫不使用direct path read的方式進行大表的全表掃描。但是這個事件只在表的大小小於5倍的buffer cache時產生作用。因此,結合10949事件,確保隱含引數"_very_large_object_threshold",使該引數值小於被掃描的表物件的0.8倍大小,即可禁止direct path read進行全表掃描。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24582392/viewspace-704305/,如需轉載,請註明出處,否則將追究法律責任。

相關文章