MySQL官方對索引的定義:索引是幫助MySQL高效獲取數據的數據結構。索引是在存儲引擎中實現的,因此每種存儲引擎中的索引都不同。如MYISAM和InnoDB存儲引擎只支持BTree索引;MEMORY和HEAP儲存引擎能夠支持HASH和BTREE索引。mysql
這裏僅針對經常使用的InnoDB存儲引擎所支持的BTree索引進行介紹:算法
1、索引類型
先建立一個新表,用於演示索引類型sql
CREATE TABLE index_table ( id BIGINT NOT NULL auto_increment COMMENT '主鍵', NAME VARCHAR (10) COMMENT '姓名', age INT COMMENT '年齡', phoneNum CHAR (11) COMMENT '手機號', PRIMARY KEY (id) ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;
下圖是Col2爲索引列,記錄與B樹結構的對應圖,僅供參考:
一、普通索引
這是最基本的索引,沒有任何限制。數據結構
------直接建立索引 create index index_name on index_table(name);
二、惟一索引
索引列的值必須惟一,能夠有空值post
---------直接建立惟一索引 create UNIQUE index index_phoneNum on index_table(phoneNum);
三、主鍵
是一種特殊的惟一索引,必須指定爲 PRIMARY KEY,如咱們經常使用的AUTO_INCREMENT自增主鍵優化
四、多列索引
也稱爲組合索引,就是在多個字段上聯合創建一個索引spa
-------直接建立組合索引 create index index_union on index_table(name,age,phoneNum);
這裏一個組合索引,至關於在有以下三個索引:code
name;blog
name,age;排序
name,age,phoneNum;
這裏或許有這樣一個疑惑:爲何age或者age,phoneNum字段上沒有索引。這是因爲BTree索引因要遵照最左前綴原則,這個原則在後面詳細展開。
2、索引優化
一、選擇索引列
建立索引簡單,可是在哪些列上建立索引則須要好好思考。能夠考慮在where字句中出現列或者join字句中出現的列上建索引
SELECT age----不使用索引 FROM index_union WHERE NAME = 'xiaoming'---考慮使用索引 AND phoneNum = '18668247687';---考慮使用索引
二、最左前綴原則
聯合索引(name,age,phoneNum) ,B+樹是按照從左到右的順序來創建搜索樹的。如('張三',18,'18668247652')來檢索數據的時候,B+樹會優先匹配name來肯定搜索方向,name匹配成功再依次匹配age、phoneNum,最後檢索到最終的數據。也就是說這種狀況下是有三級索引,當name相同,查找age,age也相同時,去比較phoneNum;可是若是拿 (18,'18668247652')來檢索時,B+樹沒有拿到一級索引,根本就沒法肯定下一步的搜索方向。('張三','18668247652')這種場景也是同樣,當name匹配成功後,沒有age這個二級索引,只能在name相同的狀況下,去遍歷全部的phoneNum。
B+樹的數據結構決定了在使用索引的時候必須遵照最左前綴原則,在建立聯合索引的時候,儘可能將常常參與查詢的字段放在聯合索引的最左邊。
三、like的使用
通常狀況下不建議使用like操做,若是非使用不可的話,須要注意:like '%abd%'不會使用索引,而like ‘aaa%’可使用索引。這也是前面的最左前綴原則的一個使用場景。
四、不能使用索引說明
mysql會按照聯合索引從左往右進行匹配,直到遇到範圍查詢,如:>,<,between,like等就中止匹配,a = 1 and b =2 and c > 3 and d = 4,若是創建(a,b,c,d)順序的索引,d是不會使用索引的。但若是聯合索引是(a,b,d,c)的話,則a b d c均可以使用到索引,只是最終c是一個範圍值。
五、order by
order by排序有兩種排序方式:using filesort使用算法在內存中排序以及使用mysql的索引進行排序;咱們在部分不狀況下但願的是使用索引。
1
|
select
test_index
where
id = 3
order
by
id
desc
;
|
若是ID是單列索引,則order by會使用索引
1
|
select
test_index
where
id = 3
order
by
name
desc
;
|
若是ID是單列索引,name不是索引或者name也是單列索引,則order by不會使用索引。由於Mysql的一次查詢只會從衆多索引中選擇一個索引,而此次查詢中使用的是ID列索引,而不是name列索引。在這種場景下,若是想讓order by也使用索引的話,就創建聯合索引(id,name),這裏須要注意最左前綴原則,不要創建這樣的聯合索引(name,id)。
最後須要注意mysql對排序記錄的大小有限制:max_length_for_sort_data 默認爲1024;也就意味着若是須要排序的數據量大於1024,則order by不會使用索引,而是使用using filesort。