聲明:雖然題目是Oracle、但同樣適合MySQL InnoDB索引
在大多數情況下、複合索引比單欄位索引好
很多系統就是靠建立一些合適的複合索引、使效率大幅度提高
複合索引比單欄位索引複雜、有兩個原則需把握:首碼性和可選性
但是、可歎的是、國內很多IT系統開發人員沒有意識到應該優先設計複合索引
更沒有充分理解複合索引的首碼性和可選性這兩個重要原則
㈠ 首碼性(Prefixing)
在謂詞條件中、只有將複合索引的第一個欄位作為約束條件、該複合索引才會被用上
當然、存在一種例外:Index Skip Scan
這個原理強調
使用
比如:
① 假如c1的選擇性比c2高很多、且如果有大量如下查詢:
select * from t where c1= and c2= :y;
select * from t where c2= :y;
這個時候(c2,c1)比(c1,c2)好
② 有ID和CREATE_TIME這兩個欄位、一個是主鍵、一個是建立時間
按一般情況、建立複合索引時、需要將ID放在前面、
不過、如果以CREATE_TIME為查詢條件的SQL比較多、而ID的使用比較少
那麼、我們在設計時、應該把CREATE_TIME首碼
㈡ 可選性(Selectivity)
概念可見
Selectivity介紹
這個原理強調成本
比如:
① 選擇性強的欄位放在前面、可以減少 Index Range Scan 的掃描成本
② 有個稅務系統、原先的複合索引是(月份,稅務機關代號,納稅人識別號,發票代號,收費類別)
對於這個索引、最佳化器並沒有選擇走索引、而是全表掃、原因如下:
● 同一月份的記錄太多了、超過1/3、全表掃成本低
● 欄位順序沒有考慮可選性
新的複合索引是(納稅人識別號,月份,收費類別,稅務機關代號,發票代號)
㈢ 複合索引好處
① 儘可能讓一個索引為更多的SQL服務
② 複合索引是排序的、ORDER BY涉及索引欄位時、可減少排序成本
我認為呢、在為複合索引欄位排序時、應該綜合考慮權衡首碼性和可選性、絕不可偏袒任何一方