(轉)索引掃描還是全表掃描(Index Scan Or Full Table Scan)

denniswwh發表於2009-09-01

作者: | 可以任意轉載, 但轉載時務必以超連結形式標明文章原始出處 和 作者資訊 及
連結:

在大多數時候,大家都會認為Sql語句中走Index Scan比Full Table Scan快,我前面也走進了這樣的誤區(對Index Scan的理解不夠)。這兩天重新複習了一下這方面內容,並整理了一下。

[@more@]

當Oracle Optimizer(最佳化器)沒有選擇Index Scan而選擇了Full Table Scan的時候一般會是由兩種情況:
1、表沒有Analyze,Optimizer得不到statistics(統計)資料,無法評估而選擇了Full Table Scan
2、Optimizer透過得到的statistics資料後評估認為Full Table Scan將比Index Scan更快

對於第一種情況當然很好理解,而且只要執行簡單的Analyze命令就好了,然後就是Oracle Optimizer按照他的一系列演算法來進行選擇了,到這裡其實也同樣可能會遇到第二種情況,關鍵還是要看Optimizer的評估結果。

Oracle Optimizer在評估一個Index的Cost(開銷)時候,有兩個主要的關鍵指標。
Oracle官方語稱為:CF(Clustering Factor)和FF(Filtering Factor)。
用通俗一點的話來理解,CF就是指每讀入一個Index Block,對應需要讀多少個Data Block。而FF呢就是該Sql最終需要讀取的記錄集佔到了整個Table中記錄總條數的百分比。

由於透過Index來讀取資料的時候是需要先讀取Index Block然後再透過Rowid讀取相應的Data Block,每讀取一條記錄都需要讀取一次資料塊(這裡表述有點問題,已經在中解釋),這樣極有可能出現對同一個Data Block讀取多次的情況。使用索引讀取資料需要讀取的Block數目據說公式大約是這樣的(只是據說):
FF ×(CF × Index Blocks)

而對於Full Table Scan,是透過db_file_multiblock_read_count設定的值進行連續讀取整個Table的所有(HWM以下)資料塊。

所以當需要讀取表中資料越多的時候(也即是FF值比較大的時候),Index Scan花銷自然也會越大。而CF值主要受到索引中資料的排列方式影響,通常在 索引剛建立時,索引中的記錄與表中的記錄有良好的對應關係,CF 都很小;在表經過大量的插入、修改後,這種對應關係越來越亂,CF 也越來越大。這時候就需要Rebuild Index。如果出現了一個Sql語句在最初時候走了Index而執行一段時間後突然變成了Full Table Scan的情況的時候,一般都是由於CF值變大的緣故。透過Rebuild Index就可以解決。而FF 則是Oracle 根據 statistics資料所做的估計,所以需要經常Analyze Table來更新表的statistics來讓Optimizer做出正確的估計而得出最佳的執行計劃。


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

相關文章