今天學習了下關於索引的最左字首的原理,小有成就感,在這裡做乙個學習記錄,以後學習的時候可以直接找出來複習。
相信熟悉資料庫的大佬們跟索引達人們肯定都了解最索引的左字首原理,我在這裡還是再重複一下吧,文章還會結合實際例子來說明最左字首的原理。
實驗工具;mysql 5.5 + sqlyog
索引的最左字首原理:
通常我們在建立聯合索引的時候,也就是對多個字段建立索引,相信建立過索引的同學們會發現,無論是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' 這個sql語句是不會走index1索引的,select * from table where b =『1』 and c ='2' 這個語句也不會走index1索引。
什麼語句會走index1索引呢?
答案是:
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』這個sql語句,按照之前的理解,包含a欄位,會走索引,但是是不是所有欄位都走了索引呢?
我們來做個實驗:
我這裡有乙個表:
建立了乙個聯合索引,prinidandorder裡面有三個字段 parent_id, menu_order, menu_name
接下來測試之前的語句:
elect
t.*
from
sys_menu t
where t.`parent_id` = '0'
and t.`menu_name` = '系統工具'
這一句sql就相當於之前的select * from table where a = '1' and c= 『2』這個sql語句了,我們來看看解釋計畫:
這也是最左字首原理的一部分,索引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不會走。
原因如下:
索引是有序的,index1索引在索引檔案中的排列是有序的,首先根據a來排序,然後才是根據b來排序,最後是根據c來排序,
像select * from table where a = '1' and b > 『2』 and c='3' 這種型別的sql語句,在a、b走完索引後,c肯定是無序了,所以c就沒法走索引,資料庫會覺得還不如全表掃瞄c欄位來的快。不知道我說明白沒,感覺這一塊說的始終有點牽強。
文中如果出現有誤的地方麻煩大佬們指點。
索引最左字首原則
今天在觀察慢sql統計的時候,發現了乙個sql的平均耗時長,而且總的掃瞄行數大,分析對應表的ddl,發現此表中只有乙個唯一索引index1 a,b,c 但是在查詢條件中沒有帶上a欄位,導致這個查詢sql沒有走索引,從而導致了全表掃瞄。這裡涉及到乙個索引最左字首原則,我們來一起看一下。下述摘自 通常我...
最左字首原則
當b 樹的資料項是復合的資料結構,比如 name,age,的時候,b 數是按照從左到右的順序來建立搜尋樹的,比如當 張三,20,f 這樣的資料來檢索的時候,b 樹會優先比較name來確定下一步的所搜方向,如果name相同再依次比較age和 最後得到檢索的資料 但當 20,f 這樣的沒有name的資料...
索引的使用,最左字首原則
建立索引可以大大提高系統的效能。第一,通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。第二,可以大大加快資料的檢索速度,這也是建立索引的最主要的原因。第三,可以加速表和表之間的連線,特別是在實現資料的參考完整性方面特別有意義。第四,在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中...