通常在where條件中兩個及以上字段時,咱們會建聯合索引。若查詢語句:select name,address,country from people where name='XXX' and country='XXX';mysql
索引創建有下面兩種方案 A(name,country) B(country,name)。將選擇性好的字段放在前面(由於people name重複率相對於country低),因此應該建name,country索引。不管where name='XXX' and country='...' 仍是 where country='XXX' and name='...',MySQL會幫你優化查詢條件,不用擔憂查詢順序。若組合索引有四五個字段,那麼按照選擇性進行排列,選擇性好的字段放前面。sql
假設create index idx_name_address_country on t1(name,address,country);按照最左匹配有下面幾個原則,判斷查詢是否會走索引性能
1.1 若查詢的條件不包含索引的最左列,沒法使用索引 優化
where name=xxx and address=xxx and country=XXX | 能夠走索引 |
where name=xxx | 能夠走索引 |
where name=xxx and country=XXX | 能夠走部分索引 |
where address=xxx | 不能夠走索引,不包含最左列name |
where country=xxx and name=xxx | 不能夠走索引,不包含最左列name,mysql沒有優化是由於索引字段裏還包含了address |
1.2 查詢包含了索引中全部的字段,查詢效率較高,若是隻包含了索引中部分字段,查詢效率會低一些搜索引擎
where name=xxx 和 where name=xxx and country=XXX 雖然都包含了索引最左列,也能夠走索引,可是他們都只能根據name字段進行過濾數據,效率比 where name=xxx and address=xxx and country=XXX低不少spa
1.3 若是組合索引中已經包含了字段,能夠不用單獨再建索引,提升索引使用率設計
好比已經有了索引(name,address,country),就不須要在單獨建索引(name)或 (name,address)排序
1.4 沒法對組合索引中多個字段進行範圍查詢,只能按照最左原則,對最左邊第一個範圍查詢有效索引
例如create index idx_A_B_C on table(A,B,C); 紅字表示不走索引ci
A=5 | 索引 |
A BETWEEN 5 AND 10 | 索引 |
A=5 AND B BETWEEN 5 AND 10 | 索引 |
A BETWEEN 5 AND 10 AND B=5 | 部分索引 |
A IN (1,2,3) AND B=5 | 索引 |
B=5 AND ... |
不走索引 |
A = 5 AND B > 5 AND C > 10 | 部分索引 |
1.5 覆蓋索引: 即索引中包含了查詢中的全部字段,能夠避免回表查詢,減小訪問磁盤次數
1.6 利用索引的有序性,進行排序,有效減小CPU開銷,須要聽從最左原則
採用idx_A_B_C,下列查詢可以使用索引
ORDER BY A |
ORDER BY A,B |
ORDER BY A DESC, B DESC |
WHERE A = 5 ORDER BY B [ASC\DESC] |
WHERE A > 5 ORDER BY A [ASC\DESC] |
WHERE A = 5 ORDER BY A,B |
ORDER BY B |
ORDER BY A[ASC\DESC] ,B [DESC/ASC] |
1.7 其餘設計
Join查詢中鏈接字段創建索引
只返回須要的字段,避免使用select *
不使用全模糊查詢 like '%xxx%’(沒法走索引),可使用like 'XXX%'(走索引)
不等於查詢not in , =(沒法走索引)
類型不匹配,好比存了數值的字符串類型字段(如手機號),查詢時記得不要丟掉值的引號,不然沒法用到該字段相關索引
該不應在一個字段上創建索引,主要考慮選擇性,選擇性就是這個字段裏面的值重複率高不高。公式是 distinct(建索引的列)/count(*) ,區間範圍在[0,1],若是是0,表示該列中全部值都同樣,若是是1,表示該列有惟一約束。該比例越趨向於1,查詢性能越好。這是由B+Tree的性質決定的。通常狀況,status(狀態)、is_deleted(是否刪除)、sex(性別)列都不建議建索引。單號、userid等建議放在最前面。
索引設計的規約(摘自螞蟻金服&集團DB設計規範)