數據庫之聯合索引的最左匹配原則

覺得前邊文字太多可以直接看下邊的圖解

一、組合索引的最左匹配原則的成因

  • 我們創建聯合索引的時候,mysql會對我們的建立索引的字段進行排序,比如順序第一個字段先進行排序,然後對第二個字段進行排序,以此類推,就類似於order by 字段1,然後order by 字段2,第一個字段是絕對有序的,單單看其餘索引的值就無序了,按照第一個索引的順序來取出第二個索引的值,我們會發現,取出來的也是有序的(相對有序)。一般情況下,我們第二個字段就直接來判斷了。
  • 而且還有一個原因,當我們順位第一個字段建立了索引後,一般B+樹葉子節點是包含該行數據的,如果此時建立其他字段的索引,那麼這個索引是沒有包含到所有字段數據的,所以後邊的索引最好都是進行更細部分的選擇的,所以聯合查詢的時候,是優先最左匹配的。

二、原則細講

  • 最左匹配原則,非常重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就停止匹配,比如a = 3 and b =4 and d = 6,如果建立在(a,b,c,d)順序的索引,d是用不到索引的,因爲a值確定,b值順序就相對確定,中間斷開了c,線索就斷了,d就無法確定,所有走到c就不走了。如果建立(a,b,d,c)的索引則都可以用到,其中a,b,d順序可以任意調整,因爲a,b,d都確定了,a—>b—>d過程中順序都是確定的,即使我們交換他們位置,查詢優化器,也能自動換成高效查詢的順序。

  • =和in可以亂序,比如a =1 and b = 2 and c = 3,建立(啊a,b,c)索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式。

  • 前邊說到遇到範圍查詢就會停止匹配,這是因爲範圍查詢前一項順序是確定的,可以匹配上索引,到了範圍查詢這裏,依舊可以匹配上索引,但是它的下一項,因爲是相對於前一項的索引順序纔有的順序,前一項是範圍,那麼這一項便不能確定順序了。

可能圖解會更加生動

(網上借圖)
在這裏插入圖片描述

  • 這是一個建立了(a,b)索引的B+樹結構,可以看到a已經確定了絕對順序,即1,1,2,2,3,3,而b則是1,2,1,4,1,2,是亂的,但是如果我們的條件是where a=1 and b=2我們再來看,a=1的取出來後,對應的b值爲1,2,是有序的,然後便可以確定b了。
  • 如果條件是where a>1 and b=2,此時a可以確定索引,但是a可以取2,3,他們對應的b又是無序的,b無法確定,所以到了範圍查詢,後邊就不再匹配索引了

接着說匹配原則(詳細舉例)

假定有聯合索引(a,b,c),(下邊例子的索引都是這個)
做如下查詢

select * from table_name where a = '1' 
select * from table_name where a = '1' and b = '2'  
select * from table_name where a = '1' and b = '2' and c = '3'

都從最左邊開始連續匹配,都用到了索引

select * from table_name where  b = '2' 
select * from table_name where  c = '3'
select * from table_name where  b = '1' and c = '3' 

因爲都沒有走a,不能確定順序,也就無法走索引,全都是全表掃描

select * from table_name where  a > 1 and a < 3 and b > 1;

根據上邊說的遇到範圍查詢加粗樣式就停,這裏只能匹配a 的索引,後邊的順序都無法確定

select * from table_name where  a = 1 and b > 3;

這種情況,都是走索引的,b的順序因爲a的確定而相對確定

order by排序:

select * from table_name order by a,b,c limit 10;

上面這種都能走到索引,按照索引排序

select * from table_name order by b,c,a limit 10;

同時呢,它也是要符合最左原則,上面這種顛倒過來的,無法確定順序,就不能走索引

select * from table_name where a =1 order by b,c limit 10;

這個a確定了,b和c可以走索引

select * from table_name order by a limit 10;
select * from table_name order by a,b limit 10;

這種情況也是走索引

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章