有關MySQL InnoDB在索引中自動添加主鍵的問題
(一)原理
只要用戶定義的索引字段中包含了主鍵中的字段,那么這個字段就不會再被InnoDB自動加到索引中。但如果用戶的索引字段中沒有完全包含主鍵字段,InnoDB就會把剩下的主鍵字段加到索引末尾。
(二)例子
例子一:
CREATE TABLE t ( a char(32) not null primary key, b char(32) not null, KEY idx1 (a,b), KEY idx2 (b,a) ) Engine=InnoDB; |
idx1和idx2兩個索引內部大小完全一樣,沒有區別
例子二:
CREATE TABLE t ( a char(32) not null, b char(32) not null, c char(32) not null, d char(32) not null, PRIMARY KEY (a,b) KEY idx1 (c,a), KEY idx2 (d,b) ) Engine=InnoDB; |
這個表InnoDB會自動補全主鍵字典,idx1實際上內部存儲為(c,a,b),idx2實際上內部存儲為(d,b,a)
但是這個自動添加的字段、Server層是不知道的,所以 MySQL 優化器并不知道這個字段的存在。那么如果你有一個查詢:
SELECT * FROM t WHERE d=x1 AND b=x2 ORDER BY a; |
其實內部存儲的idx2(d,b,a)可以讓這個查詢完全走索引。但是由于 Server 層不知道,所以最終MySQL優化器可能選擇idx2(d,b)做過濾然后排序a字段或者直接用PK掃描避免排序。
而如果我們定義表結構的時候就定義為KEY idx2(d,b,a),那么MySQL就知道(d,b,a)三個字段索引中都有,并且InnoDB發現用戶定義的索引中包含了所有的主鍵字段,也不會再添加了,并沒有增加存儲空間。
(三)建議
因此,由衷的建議所有的MySQL DBA建索引的時候都在業務要求的索引字段后面補上主鍵字段。這沒有任何損失,但是可能給你帶來意外的驚喜哦。
posted on 2013-05-10 09:24 順其自然EVO 閱讀(242) 評論(0) 編輯 收藏 所屬分類: 數據庫