復合索引的建立需要考慮兩個方面:前導列和高選擇性
前導列:建立一個復合索引(a,b,c),a是這個復合索引的第一列稱為前導列
當我們使用到這個復合索引的時候,查詢條件中未使用到前導列,如:select * from table where b=? and c=? ,一般情況下,不會使用到該復合索引。
之所以指特殊情況是因為在ORACLE 10g中CBO完全取代RBO,CBO通過計算各種可能的執行計划所需的cost,取cost最低的執行計划作為最終的執行方案,它依賴於數據庫對象中的統計信息,像上面的sql就是依賴於table表的統計信息,根據當前的統計信息生成一個該sql的最優執行計划,統計信息在oracle中有定時job,晚上進行統計,也可以我們手動進行統計,我們可以通過dba_tables和dba_tab_partitions中的LAST_ANALYZED來查看表的具體統計信息時間。
所以當CBO全面取代RBO后,我們在未使用到復合索引的前導列時,我們有可能會使用到 INDEX SKIP SCAN(復合索引之索引跳躍掃描)
使用 INDEX SKIP SCAN有一個前提條件:在我們的查詢條件中沒有復合索引的前導列時,優化器發現我們的前導列的數據選擇性低,會將每個數值都作為常規掃描的入口,在此基礎上做一次查找,最后合並這些查詢;
高選擇性:指的是該列的數據基本都不一樣,重復性低,如主鍵等
在上面說的 INDEX SKIP SCAN使用的前提條件中,是以前導列的數據選擇性低為前提,優化器估算索引跳躍掃描的成本低於其他掃描方式的成本時,使用該索引。
但我們一般建立復合索引時應按字段可選性(即值的多少)的高低進行排列,索引的選擇性越高,針對每個不同值平均返回的行數也越少。