mysql索引失效_MySQL索引失效的底层原理
? ? ?mysql的索引在使用不當情況下會失效.
? ? 比如:使用最佳左前綴法則,大于號右邊的索引會失效,使用like索引會失效,當準備面試的時候我們為了應付面試的的時候往往會去找到這些面試題目的答案,但是往往不會去思考,為什么會失效?
? ? ? 今天文章就會仔細的分析下,什么情況下mysql的索引會失效,我們都知道,索引失效的情況下都是針對聯合索引
如下圖:
? ? ? 一個聯合索引的節點上面有兩個鍵值對,現在假設聯合索引的字段是有a和b組成的,那么現在從上面的圖可以看到:2 和 4 就代表我們的a和b連個字段組合成了一個聯合索引,然后可以仔細觀察葉子節點,左邊的葉子節點都是有序排列的,并且由小到大,所以可以看到a的優先級大于b的優先級,而右邊的則是無序的
?好的,現在我們可以分析下,為什么是最左前綴法則失效?為什么大于號右邊的會失效?為什么like會失效?
?我現在新建一個測試用戶表;
創建了一個復合索引由 phone和len_id和region_id組成的idx_phone_lan_region,然后我們可是測試一下
首先我們測試一個遵循最佳做前綴法則;
執行結果如下;
explan可以看到這條sql是執行了索引的,rows等于1,type=ref
然后我們去掉 手機號再查詢一次;
可以看到rows是掃描了一行數據,當然我這個用戶表是沒有數據的,所以只能看到rows=1,然后type=all,說明這條sql沒有走索引,
所以我們分析下,為什么沒有走索引,還是由上面的那個圖我們可以看出;
我們知道聯合索引再b+樹上的排序是先排a,當a相等的情況下再排b,然后我們剛剛看到了,條件查詢存在手機號的遵循最佳左前綴法則,首先a字段再b+樹上面是有序的,就能定位到a所在的節點,就是通過二分查找發找到a,當我們查找了第一個字段,然后再來查找第二個字段b,從圖可以看出,當a相同的情況下b也是有序的,這是時候,我們的a已經確定了,那么我們就可以再a的基礎上用二分查找發去查找b,這種情況下b也是有序的,所以它也能查找到,所以這個遵循最佳做前綴法則的sql分析下來是沒有問題的,然后我們來分析不遵循最佳最佳左前綴法則的sql;
問題出在哪里?
只有當我們a相等的情況下,b才是有序的,而上面的當我們把電話號碼去掉的情況下,b就是無序的,缺少b執行的索引的存在條件,沒有a的情況下,b肯定是無序的,所以在無序情況下我們無法找到b這個值,所以只能進行全表掃描,不會搜索引
這就是為什么要遵循最佳左前綴法則了
?然后我們看看,范圍查找的右邊,為什么索引會失效;還是看這個圖
首先我們看葉子節點,查找a>1 b=1的數據,可以看到a大于1的數據由2,3,4,分別在葉子節點可以看到,然后我們再去找b=1的數據,而a>1的數據對應的b的數據是沒有序的,這個無序的不僅僅體現在葉子節點上而且還體現在非葉子節點上,所以這種情況下b無序,還是無法進行索引匹配,
當我們% 放在左邊,放在右邊都是不走索引的,那么這又是什么原因呢?
首先解釋下% 的含義,首先我們這個%放在右邊,是去查找以1 開頭的數據,例如,111222,這個數據就可以查詢出來,但是當我們變成222111,就查詢不出來,所以這個%的意思就是這個意思,所以百分號分別在左邊,右邊,還是兩邊,分別叫做,前綴,后綴,中綴,當我們一個字符串存在b+樹里面存儲的時候,也是按照字母的大小去排序的,如下圖
你去查找以a開頭的字符串,可以按照a的順序查找到。所以當你加上%就不是前綴法則了,所以這就是like失效的原理,所以這里就可以推理出in 為什么會失效,or 為什么會失效!
所以可以總結下;
如果是復合索引,葉子節點不僅保存了復合索引的值,還有主鍵的值,這就是當你使用覆蓋索引的時候,加上主鍵也會用到索引的原因
如果是模糊查詢,如果查詢字段不包括索引字段,只有當%放到左邊時候才會用到索引,但如果是覆蓋索引,則會用到覆蓋索引,
返回查詢如果復合做前綴法則,而且查詢的數據比較少的情況下,即使沒有用到覆蓋索引,也會走索引,但是如果數據過多,則會全表掃描
凡事不能二分查找的情況下都屬于索引失效的情況
??長
按
關
注
徐賣狼
微信號 :corey
總結
以上是生活随笔為你收集整理的mysql索引失效_MySQL索引失效的底层原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么整数在python中表示d_pyt
- 下一篇: linux cmake编译源码,linu