聯合索引又叫複合索引,是MySQL的InnoDB引擎中的一個索引方式,若是一個系統頻繁地使用相同的幾個字段查詢結果,就能夠考慮創建這幾個字段的聯合索引來提升查詢效率。優化
舉個例子:code
create table `table_name`( `id` bigint(20) NOT NULL PRIMARY KEY, `a` int(11), `b` int(11), `c` varchar(22), KEY `key_a_b_c` (`a`,`b`,`c`) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
如上面的代碼其中blog
KEY `key_a_b_c` (`a`,`b`,`c`)
語句就是創建了a,b,c字段聯合索引的語句。索引
在使用聯合索引時要注意有個最左前綴原則,最左前綴原則就是要考慮查詢的字段的順序,只有遵照這個原則才能最大地提升查詢的效率,下面咱們舉個例子說明最左前綴原則。內存
創建 (a
,b
,c
)的聯合索引table
#徹底按建立的順序,能走到a,b,c3個字段的索引,評級:優化最高 SELECT * FROM tz_prod.table_name where a = 1 and b=2 and c = '3';
#換了b和c的順序,MySQL會進行優化,效率和上面的同樣,評級:優化最高 SELECT * FROM tz_prod.table_name where a = 1 and c = '3' and b=2;
#能走到a和b的索引,評級:優化最高 SELECT * FROM tz_prod.table_name where a = 1 and b=2 ;
#能走到a和b的索引,b的範圍查詢不影響優化,評級:優化最高 SELECT * FROM tz_prod.table_name where a = 1 and b<2 ;
#能走到a的索引,評級:優化最高 SELECT * FROM tz_prod.table_name where a = 1;
#能走到a的索引,評級:優化最高 SELECT * FROM tz_prod.table_name order by a ;
#只能走到a的索引走不到c的索引,若是c的離散度高則查詢效率很低,評級:優化差 SELECT * FROM tz_prod.table_name where a = 1 and c = '3';
#能走到a和b的索引走不到c的索引,b的範圍查詢使後面字段沒法走索引,評級:優化差 SELECT * FROM tz_prod.table_name where a = 1 and b<2 and c = '3';
#能走到a的索引,評級:優化最高 SELECT * FROM tz_prod.table_name where a > 1 order by a;
#能走到a的索引,走不到b索引 評級:優化差 SELECT * FROM tz_prod.table_name where a > 1 order by b;
#同上,評級:優化差 SELECT * FROM tz_prod.table_name where a > 1 order by c;
#走不到b和c的索引,最左前綴原則必須以創建索引的第一個字段做爲第一個條件,評級:最差 SELECT * FROM tz_prod.table_name where b=2 and c = '3';
MySQL會爲InnoDB的每一個表創建聚簇索引,若是表有索引會創建二級索引。聚簇索引以主鍵創建索引,若是沒有主鍵以表中的惟一鍵創建,惟一鍵也沒會以隱式的建立一個自增的列來創建。聚簇索引和二級索引都是一個b+樹,b+樹的特色是數據按必定順序存在葉子節點且每頁數據相連。通常狀況下使用索引查詢時,先查詢二級索引的b+樹,查到數據並拿數據中保存的主鍵回查聚簇索引查到全部數據。下面咱們舉個例子來重現這個過程。效率
如下面表舉例,假設表中已經存了部分數據:原理
create table `user_info`( `id` bigint(20) NOT NULL PRIMARY KEY, `name` varchar(11), `age` int(11), `phone` varchar(20), KEY `key_name_age` (`name`,`age`) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
InnoDB創建的聚簇索引和二級索引以下圖im
假如咱們想要查找名字爲zhaoliu,年齡爲30的人的信息。即name='zhaoliu',age=30數據
若是你僅僅查找id,name和age數據那麼這樣就用到了覆蓋索引,這樣就不用回查聚簇索引,在第(3)步直接返回數據便可。