mysql索引原則 區分度 MySQL索引設計原則

2021-10-18 11:52:42 字數 2941 閱讀 8306

1.最左字首原則

一般在where條件中兩個及以上欄位時,我們會建聯合索引。若查詢語句:select name,address,country from people where name='***' and country='***';

索引建立有下面兩種方案 a(name,country) b(country,name)。將選擇性好的字段放在前面(因為people name重複率相對於country低),所以應該建name,country索引。無論where name='***' and country='...' 還是 where country='***' and name='...',mysql會幫你優化查詢條件,不用擔心查詢順序。若組合索引有四五個字段,那麼按照選擇性進行排列,選擇性好的字段放前面。

假設create index idx_name_address_country on t1(name,address,country);按照最左匹配有下面幾個原則,判斷查詢是否會走索引

1.1 若查詢的條件不包含索引的最左列,無法使用索引

where name=*** and address=*** and country=***

可以走索引

where name=***

可以走索引

where name=***  and country=***

可以走部分索引

where address=***

不可以走索引,不包含最左列name

where country=***  and name=***

不可以走索引,不包含最左列name,mysql沒有優化是因為索引欄位裡還包含了address

1.2 查詢包含了索引中所有的字段,查詢效率較高,如果只包含了索引中部分字段,查詢效率會低一些

where name=*** 和 where name=***  and country=*** 雖然都包含了索引最左列,也可以走索引,但是他們都只能根據name欄位進行過濾資料,效率比 where name=*** and address=*** and country=***低很多

1.3 如果組合索引中已經包含了字段,可以不用單獨再建索引,提高索引使用率

比如已經有了索引(name,address,country),就不需要在單獨建索引(name)或 (name,address)

1.4 無法對組合索引中多個字段進行範圍查詢,只能按照最左原則,對最左邊第乙個範圍查詢有效

例如create index idx_a_b_c on table(a,b,c); 紅字表示不走索引

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 '%***%』(無法走索引),可以使用like '***%'(走索引)

不等於查詢not in , =(無法走索引)

型別不匹配,比如存了數值的字串型別字段(如手機號),查詢時記得不要丟掉值的引號,否則無法用到該欄位相關索引

2.最**擇性原則

該不該在乙個欄位上建立索引,主要考慮選擇性,選擇性就是這個字段裡面的值重複率高不高。公式是 distinct(建索引的列)/count(*) ,區間範圍在[0,1],如果是0,表示該列中所有值都一樣,如果是1,表示該列有唯一約束。該比例越趨向於1,查詢效能越好。這是由b+tree的性質決定的。一般情況,status(狀態)、is_deleted(是否刪除)、***(性別)列都不建議建索引。單號、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無法排序。

mysql 索引長度和區分度

首先 索引長度和區分度是相互矛盾的,索引長度太短,那麼區分度就很低,吧索引長度加長,區分度就高,但是索引也是要佔記憶體的,所以我們需要找到乙個平衡點 那麼這個平衡點怎麼來定?比如使用者表有個字段 username 要給他加索引,問題是索引長度多少合適?其實我們知道 百家姓裡面有百多個姓 但是大多數人...

MySQL 索引長度和區分度

首先 索引長度和區分度是相互矛盾的,索引長度太短,那麼區分度就很低,吧索引長度加長,區分度就高,但是索引也是要佔記憶體的,所以我們需要找到乙個平衡點 那麼這個平衡點怎麼來定?比如使用者表有個字段 username 要給他加索引,問題是索引長度多少合適?其實我們知道 百家姓裡面有百多個姓 但是大多數人...

mysql 索引長度與區分度的選擇

理想的索引 索引長度直接影響索引檔案的大小,影響增刪改的速度,並間接影響查詢速度 占用記憶體多 針對列中的值,從左往右擷取部分,來建索引 1 截的越短,重複度越高,區分度越小,索引效果越不好 2 截的越長,重複度越低,區分度越高,索引效果越好,但帶來的影響也越大 增刪改變慢,併間影響查詢速度.所以,...