MySQL根據SQL查詢條件的類型,歸類了幾種不一樣的索引訪問方式(access method)
1. const: 主鍵索引、惟一二級索引的等值比較,結果最多隻能是一條記錄。
1. 經過聚簇索引或惟一二級索引與常數的等值比較,來定位一條數據(惟一二級索引比較is NULL時,不是const,由於惟一二級索引不強制限制非NULL,所以查出的結果多是多條,因此不是const訪問方式)
2. ref: 對索引列的等值比較,結果多是多條記錄。
1. 普通二級索引來進行等值查詢。關鍵點在於等值查詢匹配到的結果的數量,因爲查詢指望的結果字段可能並不單單是二級索引所在的column,所以若是匹配到的結果集數量很小,那麼回表的代價和很小,若是結果數量很大,則回表的代價就很大。
2. 查詢二級索引列值爲NULL的狀況,由於普通或者惟一二級索引,都沒有強制限制非NULL,所以查詢到的結果可能會是多條的,因此是ref。
3. 對於包含多個column的索引,只要查詢條件是最左邊的連續的索引列的等值比較,也是ref
3. ref\_or\_null: 查詢二級索引值爲某個常數或者NULL(有例外狀況,若是結果太多,可能會直接全表掃描)
4. range: 利用二級索引進行區間查詢。
5. index: where條件沒法直接匹配任何索引,可是指望的結果集和查詢條件都被某個聯合索引所有覆蓋到了,所以掃描了這個索引。
6. all: 全表掃描
注意事項: 一般一次查詢只能使用一個索引,那麼當where侯廟有多個條件時,MySQL如何選擇索引呢?
1. 二級索引 + 回表
1. 假定有兩個條件A和B,且都有對應的索引,那麼先判斷使用哪一個索引的開銷較小,加入選擇了A條件
2. 根據選擇的索引定位記錄
3. 回表,根據2中定位的結果進行回表操做,從主鍵索引取到完整的數據記錄,而後再用B條件對完整的數據記錄進行過濾
2. 沒法使用索引,例: WHERE 索引條件 OR 非索引條件
1. SELECT * FROM single\_table WHERE key2 > 100 AND common\_field = 'abc';
> key2 有二級索引,common\_field沒有索引
2. 此時使用key2索引進行掃描,簡化SQL=> SELECT \* FROM single\_table WHERE key2 > 100 AND TRUE,範圍是(100,+∞\],再用common\_field進行匹配
3. 此時使用key2索引進行掃描,簡化SQL=> SELECT \* FROM single\_table WHERE key2 > 100 OR TRUE,範圍是(-∞,+∞),那麼此時,不如直接全表掃描
3. 很是複雜的查詢條件時,如何進行分析?
1. 觀察WHERE後涉及到哪幾個column
2. 觀察有哪幾個可用索引
3. 假設選擇某個索引條件,簡化SQL(注意,簡化的思路就是把與被選中索引無關的查詢條件所有替換爲TRUE),獲得二級索引的掃描範圍
4. 將掃描二級索引的到的結果,再用其他條件進行過濾
雖然一般一次查詢只會用到一個二級索引,可是在某些特定條件下,可能會用到多個索引,機索引合併
1. Intersection合併
2. Union合併
3. Sort-Union合併
4. 聯合索引的使用
關於聯合索引的使用:~~~~
- 凡凡一凡凡請問一下問什麼說多列索引有範圍查詢只能用到第一個出現的範圍查詢做爲索引,好比: select * from t where key1 > 100 and key2 = 'xxx' and key3 > 20; 若是key1,key2,key3是個聯合索引,只能用到key1索引,爲何不一樣時使用三個條件去索引中查找呢?
- 由於Key1的查詢不是等值查詢,查詢出來的Key1值也不一樣,而只有當Key1值相同時,才能讓Key2上,同理 只有全部記錄中Key2值都相同時,才輪獲得Key3,我是這麼理解
- 根據小冊第8章,個人理解是「在某條件下,某列必須是有序的,該列纔可能用上索引」。在這裏就是key1 > 100時,key2是無序的,因此沒法走key2的索引。而若是key1是等值查詢,則key2有序,能夠用上key2的索引。
聯合索引的使用,涉及到了聯合索引的排序方式,它是按照索引列從左向右依次進行排序的。因此,當指望用到其中某個索引列時,該列必須是有序的,也就是說,這個列左側的索引列,已經經過等值查詢匹配過了。