㈠ 原理:
只要使用者定義的索引欄位中包含了主鍵中的欄位、那麼這個欄位就不會再被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 建索引的時候、都在業務要求的索引欄位後面補上主鍵欄位、
這沒有任何損失、但是可能給你帶來意外的驚喜哦