mysql最左前綴原則


為什么要有索引 

  假設我們要查找以下SQL語句,如果沒有索引我們就會掃描整張物理表

SELECT `uid` FROM people WHERE lname`='Liu'  AND `fname`='Zhiqun' AND `age`=26 

   假設建有單列索引index(lname),那么系統就會先到lname索引表中查找得到符合條件的people主鍵值,然后通過主鍵值掃描people表,進行剩下的匹配,這樣就大大地提高效率。

  為了提高搜索效率,我們需要考慮運用多列索引,由於索引文件以B-Tree格式保存,所以我們不用掃描任何記錄,即可得到最終結果。

 

 

索引的最左前綴原理:

  通常我們在建立聯合索引的時候,也就是對多個字段建立索引,相信建立過索引的同學們會發現,無論是oralce還是mysql都會讓我們選擇索引的順序,比如我們想在a,b,c三個字段上建立一個聯合索引,我們可以選擇自己想要的優先級,a、b、c,或者是b、a、c 或者是c、a、b等順序。為什么數據庫會讓我們選擇字段的順序呢?不都是三個字段的聯合索引么?這里就引出了數據庫索引的最左前綴原理。

  比如:索引index1:(a,b,c)有三個字段,我們在使用sql語句來查詢的時候,會發現很多情況下不按照我們想象的來走索引。比如以下兩種情況

select * from table where c = '1'
select * from table where b =‘1’ and c ='2' 

  以下三種會走索引

select * from table where a = '1'  

select * from table where a = '1' and b =2’  

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

  從以上兩個代碼組可知看出,所有走索引index1的sql語句的查詢條件里面都帶有a字段,那么問題來了,index1的索引的最左邊的列字段是a,是不是查詢條件中包含a就會走索引呢?例如:

select * from table where a = '1' and c=2

  按照之前的理解,包含a字段,會走索引,但是是不是所有字段都走了索引呢?

 

我們來做個實驗:

  我這里有一個表

 

  接下來測試之前的語句:

EXPLAIN select * from indextest where a = 2 and c = "艷 耀 董"

  這一句sql就相當於之前的select * from table where a = '1' and c= ‘2’這個sql語句了,我們來看看解釋計划:

  可以看到走了索引prinIdAndOrder,但是旁邊的key_len=303,但道理key_len應該是大於303的,為什么呢?

  因為PARENT_ID字段的類型是varchar(100) NULL,所以key_len=100*3+2+1=303,但是還有MENU_NAME呢!具體的key_len的計算方法,大家可以百度,我的表的字符集是utf-8,不同字符集的表的計算方式不一樣。這里的解釋計划顯示key_len只有303,說明只是走了字段PARENT_ID的索引,沒有走MENU_NAME的索引。

  這也是最左前綴原理的一部分,索引index1:(a,b,c),只會走a、a,b、a,b,c 三種類型的查詢,其實這里說的有一點問題,a,c也走,但是只走a字段索引,不會走c字段。

另外還有一個特殊情況說明下,select * from table where a = '1' and b > ‘2’  and c='3' 這種類型的也只會有 a與b 走索引,c不會走。

  像select * from table where a = '1' and b > ‘2’  and c='3' 這種類型的sql語句,在a、b走完索引后,c肯定是無序了,所以c就沒法走索引,數據庫會覺得還不如全表掃描c字段來的快。不知道我說明白沒,感覺這一塊說的始終有點牽強。

 

  最左前綴:顧名思義,就是最左優先,上例中我們創建了lname_fname_age多列索引,相當於創建了(lname)單列索引,(lname,fname)組合索引以及(lname,fname,age)組合索引。 

 

 最左側規范

  (1)在創建多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。

  

 最左前綴是什么?

  最左前綴是針對組合索引而言的,那么組合索引有什么好處?

    以index (a,b,c)為例建立這樣的索引相當於建立了索引a、ab、abc三個索引。一個索引頂三個索引當然是好事,畢竟每多一個索引,都會增加寫操作的開銷和磁盤空間的開銷。

    最左前綴:顧名思義,就是最左優先,上例中我們創建了lname_fname_age多列索引,相當於創建了(lname)單列索引,(lname,fname)組合索引以及(lname,fname,age)組合索引。 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM