MySQL索引設計原則

1.最左前綴原則

通常在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 , =(沒法走索引)

類型不匹配,好比存了數值的字符串類型字段(如手機號),查詢時記得不要丟掉值的引號,不然沒法用到該字段相關索引

2.最大選擇性原則

該不應在一個字段上創建索引,主要考慮選擇性,選擇性就是這個字段裏面的值重複率高不高。公式是 distinct(建索引的列)/count(*) ,區間範圍在[0,1],若是是0,表示該列中全部值都同樣,若是是1,表示該列有惟一約束。該比例越趨向於1,查詢性能越好。這是由B+Tree的性質決定的。通常狀況,status(狀態)、is_deleted(是否刪除)、sex(性別)列都不建議建索引。單號、userid等建議放在最前面。

3.總結

索引設計的規約(摘自螞蟻金服&集團DB設計規範)

  • 索引不是越多越好,越多的索引帶來的就是更高的索引維護成本,包含CPU計算消耗,索引創建時增長的IO開銷等,所以必定要合理創建索引;
  • 表被索引列必須定義爲not null,並設置default值;
  • 超過三個表禁止join。須要join的字段,數據類型保持絕對一致;多表關聯查詢時,保證被關聯的字段須要有索引;
  • 在varchar字段上創建索引時,必須指定索引長度,不必對全字段創建索引,根據實際文本區分度決定索引長度。通常對字符串類型數據,長度爲20的索引,區分度會高達90%以上,可使用count(distinct left(列名, 索引長度))/count(*)的區分度來肯定。
  • 頁面搜索嚴禁左模糊或者全模糊,若是須要請走搜索引擎來解決。索引文件具備B-Tree的最左前綴匹配特性,若是左邊的值未肯定,那麼沒法使用此索引;
  • 若是有order by的場景,請注意利用索引的有序性。order by 最後的字段是組合索引的一部分,而且放在索引組合順序的最後,避免出現file_sort的狀況,影響查詢性能。正例:where a=? and b=? order by c; 索引:a_b_c 反例:索引中有範圍查找,那麼索引有序性沒法利用,如:WHERE a>10 ORDER BY b; 索引a_b沒法排序。
相關文章
相關標籤/搜索