MySql最左字首原則

2021-08-18 10:16:35 字數 2897 閱讀 8030

**

企業的筆試題,對資料庫這塊了解很淺,所以還是記錄一下吧。

b-tree 索引和 hash 索引的對比

對於 b-tree 和 hash 資料結構的理解能夠有助於**不同儲存引擎下使用不同索引的查詢效能的差異,尤其是那些允許你選擇 b-tree 或者 hash 索引的記憶體儲存引擎。

b-tree 索引的特點

b-tree 索引可以用於使用 =, >, >=, <, <= 或者 between 運算子的列比較。如果 like 的引數是乙個沒有以萬用字元起始的常量字串的話也可以使用這種索引。

有時,即使有索引可以使用,mysql 也不使用任何索引。發生這種情況的場景之一就是優化器估算出使用該索引將要求 mysql 去訪問這張表的絕大部分記錄。這種情況下,乙個表掃瞄可能更快,因為它要求更少量的查詢。但是,如果這樣的乙個查詢使用了 limit 來檢索只是少量的記錄時,mysql 還是會使用索引,因為它能夠更快地找到這點記錄並將其返回。

hash 索引的特點

hash 索引有著與剛才所討論特點的相比截然不同的特點: 

hash 索引只能夠用於使用 = 或者 <=> 運算子的相等比較(但是速度更快)。hash 索引不能夠用於諸如 < 等用於查詢乙個範圍值的比較運算子。依賴於這種單值查詢的系統被稱為 「鍵-值儲存」;對於這種系統,盡可能地使用 hash 索引。 

優化器不能夠使用 hash 索引來加速 order by 操作。這種型別的索引不能夠用於按照順序查詢下乙個條目。 

mysql 無法使用 hash 索引估計兩個值之間有多少行(這種情況由範圍優化器來決定使用哪個索引)。如果你將一張 myisam 或 innodb 表轉換成乙個 hash 索引的記憶體表時,一些查詢可能會受此影響。 

查詢某行記錄必須進行全鍵匹配。而 b-tree 索引,任何該鍵的左字首都可用以查詢記錄。

最左字首原則

通過例項理解單列索引、多列索引以及最左字首原則

例項:現在我們想查出滿足以下條件的使用者id: 

mysql>select `uid` from people where lname`=』liu』 and `fname`=』zhiqun』 and `age`=26 

因為我們不想掃瞄整表,故考慮用索引。

單列索引: 

alter table people add index lname (lname); 

將lname列建索引,這樣就把範圍限制在lname=』liu』的結果集1上,之後掃瞄結果集1,產生滿足fname=』zhiqun』的結果集2,再掃瞄結果集2,找到 age=26的結果集3,即最終結果。

由 於建立了lname列的索引,與執行表的完全掃瞄相比,效率提高了很多,但我們要求掃瞄的記錄數量仍舊遠遠超過了實際所需 要的。雖然我們可以刪除lname列上的索引,再建立fname或者age 列的索引,但是,不論在哪個列上建立索引搜尋效率仍舊相似。

2.多列索引: 

alter table people add index lname_fname_age (lame,fname,age); 

為了提高搜尋效率,我們需要考慮運用多列索引,由於索引檔案以b-tree格式儲存,所以我們不用掃瞄任何記錄,即可得到最終結果。

注:在mysql中執行查詢時,只能使用乙個索引,如果我們在lname,fname,age上分別建索引,執行查詢時,只能使用乙個索引,mysql會選擇乙個最嚴格(獲得結果集記錄數最少)的索引。

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

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

拓展:在網上看到乙個關於最左字首原則提出這麼乙個例子。

多列欄位做索引,state/city/zipcode,想要索引生效的話,只能使用如下的組合 

state/city/zipcode 

state/city 

state 

其他方式(如city,city/zipcode),則索引不會生效 

這種現象是怎麼導致的?和索引的儲存方式有關嗎?

本人頁參考了下其他網友的觀點,個人認為,所謂最左字首原則就是先要看第一列,在第一列滿足的條件下再看左邊第二列,以此類推。有位網友描述得很形象: 

你可以認為聯合索引是闖關遊戲的設計

例如你這個聯合索引是state/city/zipcode

那麼state就是第一關 city是第二關, zipcode就是第三關

你必須匹配了第一關,才能匹配第二關,匹配了第一關和第二關,才能匹配第三關

你不能直接到第二關的

索引的格式就是第一層是state,第二層才是city

索引是因為b+樹結構 所以查詢快 如果單看第三列 是非排序的。 

多列索引是先按照第一列進行排序,然後在第一列排好序的基礎上再對第二列排序,如果沒有第一列的話,直接訪問第二列,那第二列肯定是無序的,直接訪問後面的列就用不到索引了。 

所以如果不是在前面列的基礎上而是但看後面某一列,索引是失效的。大家有不同的觀點可以提出,這是個人理解的觀點。

解釋一下最左字首原則:

2.當b+樹的資料項是復合的資料結構,比如(name,age,***)的時候,b+數是按照從左到右的順序來建立搜尋樹的,比如當(張三,20,f)這樣的資料來檢索的時候,b+樹會優先比較name來確定下一步的所搜方向,如果name相同再依次比較age和***,最後得到檢索的資料;但當(20,f)這樣的沒有name的資料來的時候,b+樹就不知道下一步該查哪個節點,因為建立搜尋樹的時候name就是第乙個比較因子,必須要先根據name來搜尋才能知道下一步去**查詢。比如當(張三,f)這樣的資料來檢索時,b+樹可以用name來指定搜尋方向,但下乙個欄位age的缺失,所以只能把名字等於張三的資料都找到,然後再匹配性別是f的資料了, 這個是非常重要的性質,即索引的最左匹配特性。

sql優化

這裡面講解的很好。

MySql最左字首原則

最左字首原則 通過例項理解單列索引 多列索引以及最左字首原則 例項 現在我們想查出滿足以下條件的使用者id mysql select uid from people where lname liu and fname zhiqun and age 26 因為我們不想掃瞄整表,故考慮用索引。單列索引 ...

mysql最左字首原則

假設資料 表 t a,b,c rowid 為物理位置 rowid a b c 1 111 2 2 113 3 2214 4 1 33 5 2312 6 1 25 7 239 8 1 22 9 136 10 2 211 11 228 12 1 17 13 2315 14 1 14 15 2110 當你...

最左字首原則

當b 樹的資料項是復合的資料結構,比如 name,age,的時候,b 數是按照從左到右的順序來建立搜尋樹的,比如當 張三,20,f 這樣的資料來檢索的時候,b 樹會優先比較name來確定下一步的所搜方向,如果name相同再依次比較age和 最後得到檢索的資料 但當 20,f 這樣的沒有name的資料...