提要:
查詢特定的要求:
智能掃描只可用於完整的表或索引掃描。
智能掃描只能用於直接路徑讀取:
直接路徑讀取會自動用於並行查詢。
直接路徑讀取能夠用於串行查詢。
默認狀況下不使用它們進行小型表的串行掃描。
使用 _serial_direct_read=TRUE 可強制執行直接路徑讀取。算法
爲了查詢能夠得到Exadata卸載能力的優點,優化器必須決定使用全表掃描或者快速全索引掃描來執行語句,這裏的用詞比較籠統,通常來講,這兩個詞對應的是執行計劃中的TABLE ACCESS FULL和INDEX FAST FULL SCAN。在Exadata中,這些相似的操做的命名作了些許更改以代表訪問的是Exadata存儲。新的操做名稱是TABLE ACCESS STORAGE FULL和INDEX STORAGE FAST FULL SCAN。請注意,也有一些細微的變化,好比 MAT_VIEW ACCESS STORAGE FULL事件也表示可使用智能掃描。不過你應該知道,事實上就算執行計劃裏面顯示 TABLE ACCESS STORAGE FULL操做,也並不意味着查詢就必定執行了智能掃描,它僅僅意味着前提已經知足。咱們將在本章稍後探討如何確認一個語句是否確實經過智能掃描實現了卸載操做。數據庫
直接路徑讀是什麼意思?下面兩段話能夠解釋
智能掃描除了必須是全掃描以外,還須要讀取操做是經過Oracle直接路徑讀取機制來執行的。直接路徑讀取已經存在很長一段時間了,傳統上,這種讀取機制是被服務於並行查詢的從屬進程(Slave Process)使用的。由於並行查詢最初預計將用於訪問很是大量的數據(一般大到沒法所有放入Oracle緩衝區),因此決定並行從屬進程直接讀取數據,而後放入本身的內存中(也被稱爲程序全局區或者PGA)。直接路徑讀取機制徹底跳過了標準的將數據庫放入緩衝區這樣的Oracle緩存機制,這對海量數據是很是有效的,由於它消除了那些額外的沒有幫助的工做(緩存全表掃描獲取到的卻又可能不會被再次用到的數據),讓這些塊不至於將其餘的數據塊刷新出緩衝區。像咱們以前提到的,kcfis(Kernel File Intelligent Storage)函數是被kcbldrget( Kernel Block Direct Read GET)函數調用的,因此,智能掃描只有在使用直接路徑讀取機制的時候纔會執行。緩存
除了並行從屬進程,只要條件容許,直接路徑讀取也可能用在非並行SQL語句中。有一個隱含參數_SERIAL_DIRECT_READ能夠控制此功能。當此參數設置爲默認值AUTO時,Oracle自動判斷是否要爲非並行掃描使用直接路徑讀取。計算基於幾個因素,包括對象大小、Buffer Cache大小,以及在Buffer Cache中已存在了多少該對象的數據塊。另外,還有一個隱含參數(_SMALL_TABLE_THRESHOLD)定義了若是要使用串行直接路徑讀取,那麼表至少要爲多大。對於非串行掃描決定是否要使用直接路徑讀取機制的算法並未公開,雖然串行直接路徑讀取的功能早已存在,可是隻是在最近才成爲比較廣泛的現象。Oracle數據庫11gR2在計算是否對於非並行掃描使用直接路徑讀取上作了一些修改,新修改的算法使Oracle 11gR2比之前的數據庫版本要更頻繁地採用直接路徑讀取。這也許是由於有了Exadata智能掃描,所以但願儘量地觸發直接路徑讀取,可是這樣的算法在非Exadata平臺上可能略顯激進。函數
備註 My Oracle Support文檔:793845.1中包含以下表述。
在11g中,關於在串行表掃描中是使用直接路徑讀取仍是使用緩存讀取,咱們作了探索性的改動。在10g中,對於大表的串行掃描默認是經過緩存的,在11g中,決定是直接讀取仍是經過緩存讀取,要基於表大小、緩衝區大小和其餘多種統計信息。由於避免了閂鎖(Latche),所以直接路徑讀取比離散讀(Scattered Read)更快,對其餘進程影響更小。性能
徹底索引掃描和快速徹底索引掃描的區別:優化
徹底索引掃描: 這個性能感受是最差的,只能單塊讀取,並且還要經過表去得到數據,可是由於他是按索引的順序讀取的,因此再也不須要排序. 好比 select * from table order by name, 若是name 上有索引,很顯然這個時候通常有2個計劃, 第一個,全表掃描,而後sort, 還有一個狀況,徹底索引掃描就OK. 由於此時不須要排序了.
索引全掃描是根據葉節點鏈來進行的。進行索引全掃描首先要從根開始,找到葉節點鏈上的第一個數據塊,而後沿着葉節點鏈進行掃描,因爲葉節點鏈是根據索引鍵值排序的,所以這樣掃描出來的數據自己就是排序的,數據讀出後不須要再次排序。這種掃描方式和索引快速全掃描相比,首先要找到索引的根,而後經過枝節點找到第一個葉節點,而後再順着葉節點鏈掃描整個索引。索引全掃描的IO成本比索引快速全掃描要大不少,讀取根節點和葉節點的成本相對不大,不過因爲順着葉節點鏈掃描整個索引的時候沒法使用多塊讀,而只能使用單塊讀,所以這種掃描方式的IO開銷要遠大於索引快速全掃描。這種索引掃描,咱們若是對會話進行跟蹤,會發現大量的db file sequential read等待。對象
快速徹底索引掃描:
屬先這個掃描是不用經過表獲得數據的.這個是重點. 那麼不經過表獲得數據,很明顯只能經過索引獲得數據了. 那就更明顯了,那你要拿的字段必須在索引中,否者如何不經過表的到數據?一般好比:select name from table; 若是name上有索引,有可能走FFS.可是若是是select name,id from table,假如id沒有索引,那麼無論怎麼樣,都是不可能走FFS的.對索引的掃描能夠根據該索引的extent來進行,採用多塊讀的方式進行。所以在這類操做中,咱們能夠看到會話會大量的出現db file scattered read等待。
後者是咱們但願在EXADATA上出現的索引掃描方式排序