mysql多個字段建立組合索引時候,字段順序可以隨意,但最好是遵循一定順序的,如索引(a,b,c)與(b,a,c)肯定不一樣的,順序不一樣索引的效果也不一樣,所以要計算其先後順序。
如表mc_k12_wechat_user_info有如下字段
1、計算組合索引建立的順序
1、常用的字段放在最前面
現在要建立組合索引(phone_number,provice),phone_number肯定是經常差的,要放在前邊,provice不經常查,放在後邊
2、等值條件儘量在前邊
等值條件儘量在前邊,在掃描的時候,找到的索引塊都是有效數據。若非等值條件放在前邊,那麼需要進行索引跳躍掃描,或者範圍掃描,這是就掃描了很多無效的索引,非等值條件放在後邊可以,減少無效的索引掃描,提高查找效率。
3、離散值較高的字段往前放
現在要建立組合索引(phone_number,union_id,open_id)
SELECT
COUNT(DISTINCT phone_number)/COUNT(*) phone_number,
COUNT(DISTINCT union_id)/COUNT(*) union_id ,
COUNT(DISTINCT open_id)/COUNT(*) open_id
from mc_k12_wechat_user_info
結果如下,按照ji計算值由大到小的順序建立組合索引,值越大表明該字段不爲空索引命中的機率越大。
由計算結果可以看到 open_id > phone_number > union_id,組合索引建立的順序就是(open_id,phone_number,union_id)
ALTER TABLE mc_k12_wechat_user_info INDEX idx_wechat_user_info (open_id,phone_number,union_id)
2、EXPLAIN 之key_len計算規則
各種數據類型計算規則如下:
char和varchar類型key_len計算公式:
varchr(N)變長字段且允許NULL = N * ( character set:utf8=3,gbk=2,latin1=1)+1(NULL)+2(變長字段)
varchr(N)變長字段且不允許NULL = N * ( character set:utf8=3,gbk=2,latin1=1)+2(變長字段)
char(N)固定字段且允許NULL = N * ( character set:utf8=3,gbk=2,latin1=1)+1(NULL)
char(N)固定字段且允許NULL = N * ( character set:utf8=3,gbk=2,latin1=1)
數值數據的key_len計算公式:
TINYINT允許NULL = 1 + 1(NULL)
TINYINT不允許NULL = 1
SMALLINT允許爲NULL = 2+1(NULL)
SMALLINT不允許爲NULL = 2
INT允許爲NULL = 4+1(NULL)
INT不允許爲NULL = 4
日期時間型的key_len計算:(針對mysql5.5及之前版本)
DATETIME允許爲NULL = 8 + 1(NULL)
DATETIME不允許爲NULL = 8
TIMESTAMP允許爲NULL = 4 + 1(NULL)
TIMESTAMP不允許爲NULL = 4
3、舉例說明索引idx_union_id的計算規則
EXPLAIN 查看執行計劃
EXPLAIN SELECT * from mc_k12_wechat_user_info where union_id = 'oNC5b6PvqwyLCpbc8b1aPMLNrtgk'
看到key_len=194
查看錶結構
desc mc_k12_wechat_user_info
可以看到union_id的字段類型爲varchar,長度爲64且不允許爲空,表字符編碼爲utf8
所以key_len= varchar(64) * utf8(3) + 2 = 64 * 3 + 2 = 194
組合索引遵循索引最左原則,組合索引的key_len計算亦遵循此原則,以最左邊的索引字段長度爲計算準則