叢集索引就是innodb預設建立的基於主鍵的索引結構,表裡的資料就是直接放在叢集索引裡,作為葉節點的資料頁:
基於主鍵的資料搜尋:從叢集索引的根節點開始進行二分查找,一路找到對應資料頁,基於頁目錄就直接定位到主鍵目標資料。
若想對其它欄位建立索引,甚至是基於多個欄位建立聯合索引,此時索引結構又是咋樣?
假設對其他欄位建立索引,如name、age之類,都是一樣原理。例如你插入資料時:
把完整資料插入叢集索引的葉節點的資料頁,同時維護好叢集索引
為你其他欄位建立的索引,重新再建立一顆B 樹
例如你基於name欄位建立了一個索引,當插入資料時,就會重新搞一顆B 樹,B 樹的葉節點也是資料頁,但該資料頁裡僅放主鍵欄位和name欄位:
這是一個基於B 樹的name欄位獨立於聚簇索引的索引結構,其葉節點儲存的資料僅包含主鍵和name欄位的值。
整體排序規則都跟叢集索引依照主鍵的排序規則是一樣,也就是:
葉節點的資料頁中的name值都是排序的
下一個資料頁裡的name欄位值都>上一個資料頁裡的name欄位值
name欄位的索引B 樹也會建立多層級的索引頁,索引頁裡存放:
下一層的頁號
最小name欄位值,根據name字段值排序。
所以若你根據name欄位查數據,過程也一樣,從name索引樹的根節點開始,一層一層往下找,一直找到葉節點的數據頁,定位到name欄位值對應的主鍵值。
接著針對
select * from t where name='xx'
這種語句,先根據name值在name索引樹裡找,找到葉節點,也只能找到對應主鍵值,而找不到這行數據的所有字段。
所以還需回表:還需根據主鍵值,再到叢集索引裡從根節點開始,找到葉節點的資料頁,定位到主鍵值對應的完整資料行,此時才能把select *
要的全部欄位值都取出。
例如name age,運行流程同理,建立一個獨立的B 樹,葉節點的資料頁存放id name age後,預設按name排序,name一樣就按age排,不同資料頁之間的name age值的排序也是如此。
然後這個name age的聯合索引的B 樹的索引頁存放:
下一層節點的頁號
最小的name age的值
所以當你根據name age搜尋時,就會走name age聯合索引樹,搜尋到主鍵,再根據主鍵到叢集索引裡去搜尋。
以上是MySQL二級索引查詢過程是怎麼樣的的詳細內容。更多資訊請關注PHP中文網其他相關文章!