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 為什麼會失效!
所以可以總結下;
如果是復合索引,葉子節點不僅儲存了復合索引的值,還有主鍵的值,這就是當你使用覆蓋索引的時候,加上主鍵也會用到索引的原因
如果是模糊查詢,如果查詢欄位不包括索引字段,只有當%放到左邊時候才會用到索引,但如果是覆蓋索引,則會用到覆蓋索引,
返回查詢如果復合做字首法則,而且查詢的資料比較少的情況下,即使沒有用到覆蓋索引,也會走索引,但是如果資料過多,則會全表掃瞄
凡事不能二分查詢的情況下都屬於索引失效的情況
MySQL索引底層(二) 索引底層原理
聚集索引 上次我們講到了主鍵的索引,我們可以執行一下sql語句 explain select from t user where a 1 我們可以看到這條sql走的是主鍵的索引,而在mysql的innodb中,主鍵索引則是聚集索引,資料的物理順序與鍵值的邏輯 索引 順序相同,其實就是說主鍵索引跟其他...
MySQL索引底層原理
通過hash演算法,能快速檢索資料 資料碰撞問題用鏈位址法 無法進行範圍搜尋 解決雜湊索引無法範圍搜尋的問題 極端情況下會退化成線性鍊錶,自增主鍵必然會導致極端情況 會自動調整樹形態,使其保持平衡,調整會消耗效能 無法完全解決二叉查詢樹的問題 絕對平衡的二叉樹,更耗效能 根本解決了紅黑數的問題 由於...
mysql索引底層原理
索引的本質 資料結構 組織資料的方式 innodb沒有主鍵索引時,判斷是否含有唯一索引,沒有唯一就生成乙個隱藏的row id作為主鍵 在資料較少時是以鍊錶的形式儲存資料的,當資料過多,長鍊表會影響資料的查詢,此時會將資料通過頁的形式進行儲存,預設一頁儲存16kb資料,每頁會與每頁之間通過指標進行連線...