【oracle調優】表掃描還是索引掃描
在資料庫優化的時候,最常用的手段就是建索引了。但實際情況是建了索引,資料庫也不一定會走索引,我們首先來看看,優化器根據什麼決定走索引還是走全表。
1、查詢出來的記錄數
優化器顯示的返回的記錄數為優化器估計的數值,並不一定是實際查出來的記錄數。在對列有直方圖的情況下,這個預估值就會更接近真實值。在沒有直方圖的情況下,這個值有時候會跟實際值差很多,以致可能直接影響對索引的選擇。
比如公司員工100人,年齡為30-50,年齡唯一值有20個,但這個欄位值分佈很不均,其中實際35歲的就有50人,比如我要查詢年齡為35歲的人,若沒有直方圖,則優化器預估的返回記錄數應該為100/20=5個,而實際要返回50個。這就很有可能造成優化器傾向選擇效能可能更差的索引。
所以,對於資料分佈很不均的列,要建立直方圖。
建立直方圖的引數是統計分析中的
Method_opt 這個是確定在哪些列上建立柱狀圖的選項。(只列出了for all
columns相關的)
For all columns size repeat.只在原本有柱狀圖的列上進行柱狀圖分析重建。
For all columns size skewonly.分析所有列資料的分佈情況,根據此情況決定在哪些列上建立柱狀圖。比較耗費系統資源。
For all columns size auto。根據列資料分佈情況和負載情況決定如何建立柱狀圖。
2、記錄的長度
也就是每行的平均長度。記錄的長度越長,計算出的塊讀取數越多,也就越傾向於走索引。
可以從dba_tab_statistics檢視中的AVG_ROW_LEN檢視。
該值也是在統計分析後才能得到最準確的值。
3、資料分佈
也就是聚簇因子的值。
當表資料大致是按照索引的順序儲存的時候,則通過索引找到rowid之後,則可以通過讀取更少的資料塊就能查詢出結果集。這種情況下,資料庫走索引的花費也將趨於更少。
可以從dba_ind_statistics檢視中的CLUSTERING_FACTOR檢視該值。
該值最優為等於表的blocks數,最差等於表的row數。
若該值的正確值仍對查詢造成了不理想的效果,也可通過dbms_stats.set_index_stats函式進行修改。
4、優化器目標
優化器目標引數OPTIMIZER_MODE預設是ALL_ROWS,其他可設的值還有FIRST_ROWS、FIRST_ROWS_n(n為1、10、100或1000)。
全表掃描可以在目標為ALL_ROWS的時候獲得更快的響應時間,若你更傾向於更快得到前部分資料,更傾向於讓你的查詢走索引,則設定為FIRST_ROWS_N可能更好。
5、兩個關於索引的引數
Optimizer_index_caching
該引數預設為0,取值範圍為0-100,優化器根據該值計算預估用於巢狀迴圈聯結的索引塊有多少比例已經存在於資料緩衝區。該值設定的大些,更有利於優化器選擇索引,選擇巢狀迴圈方式的聯結。
Optimizer_index_cost_adj
該值預設是100,取值範圍為0-10000,優化器根據該值計算索引掃描和全表掃描的花費,即預設索引掃描和全表掃描的花費是一樣的。
通過給該值一個更小的值,可以讓優化器更傾向於走索引。
原本db_file_multiblock_read_count的值也會影響優化器計算全表掃描的花費,但10gR2之後,該值已經可以自調節,不在需要手動調整了。
6、HINT
當然,也可以通過oracle提供的方法顯式的決定執行計劃,儲存提綱、固話基線以及我們要說的這個hint提示。
提示全表掃描
/*+FULL(表名)*/
提示走索引
/*+INDEX(表名 索引名)*/
7、表掃描還是索引掃描
說了以上那麼多,只是說明了優化器是根據什麼決定表掃描還是索引掃描的,但是優化器有時候會根據錯誤的資訊(比如過時的統計資訊、不合適的引數設定)得到可能並不合適的執行計劃。這是就需要我們去思考究竟是表掃描還是索引掃描這個問題了。
最直接適用的一點就是目標資料的佔比。
當然這個佔比無法給出一個確切的比例,主要因為row的長度不一定,所以,基本上。要得到的資料佔整個表的大部分,則全表掃描更合適,然只是整個表的很小一部分,則索引掃描通常更好。