1. 程式人生 > 實用技巧 >MySQL-索引失效原理

MySQL-索引失效原理

一、聯合索引的B+樹

索引失效我們針對的是聯合索引,我們之前有講到過,在沒有遵守最佳左法則或者使用like或者使用百分號的情況下索引會失效。但是到底為什麼索引失效了並沒有解釋。索引失效和innodb引擎的B+樹儲存方式有關。我們知道單索引的B+樹是這樣的。

聯合索引的B+樹也相差不多,因為聯合所有有多個欄位,下面的圖以兩個欄位為例子,比如兩個欄位為(a,b),其實和單值索引的不同至少他的鍵值對不是一個,而是多個

我們現在分析這個構建出來的樹

當我們只分析a時,會發現a是有序的,1,1,2,2,3,3
當我們只分析b時,會發現b是無序的,1,2,1,4,1,2
但是如果我們先根據a排序,再來看b,就會發現在a確定的情況b其實也是有序的。
這個就是我們聯合索引命中的原理。即a本身有序,在a確定的情況下,b又是有序的,所以就相當於都是有序的

二、最佳左字首法則

根據上圖我們就可以理解為什麼在我們沒有遵守最佳左字首法則的時候無法命中索引。看下面的例子

select * from test where a=1 and b=2;
-- 上述語句是直接命中索引的,首先找a,a是有序的,在確定了a之後找b,在a確定後b也是有序的。

select * from test where b=2;
-- 上述語句未命中索引,此時在構建的樹中,b是無序的,無法使用二分查詢。mysql找無序的資料就是全表掃描。

三、範圍查詢右邊失效原理

其實和上面相同,當你使用了範圍查詢,能夠鎖定部分的a值,但是去除掉了這些a之後,還有許多其他的a值繫結的b值依然是無序的。

select * from test where a>1 and b=2;

要找到一個b有序的前提是缺點a的值,範圍查詢中大於a的值可能是一個,也可能是一百萬個。

四、like索引失效原理

like一般要配合百分號,一般是查字元型別的。在mysql裡字元會按照自己的演算法排好,當然也是從小到大,如字母就是用ascii碼錶排序。

a%代表找以a開頭的所有,a叫字首
%a%代表任意包含a的值,a叫中綴
%a代表找以a結尾的所有,a叫字尾

根據我們之前是結論,要命中索引必須要確定a的值,那麼只有a%是符合的,因為後兩種都無法確定前面的值,但是這種僅僅只有一個a%其實也是很難命中索引的,因為a開頭的值可能有一個,也可能一百萬個。