InnoDB 索引實現

雖然 InnoDB 也使用 B+Tree 作爲索引結構,但具體實現方式卻與 MyISAM 截然不同。InnoDB 的數據文件本身就是索引文件。MyISAM 索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。

而在InnoDB 中,表數據文件本身就是按 B+Tree 組織的一個索引結構,這棵樹的葉子節點保存了完整的數據記錄。這個索引的 key 是數據表的主鍵,因此 InnoDB 表數據文件本身就是主索引。
MySQL索引實現原理分析

上圖是 InnoDB 主索引(同時也是數據文件)的示意圖,可以看到葉節點包含了完整的數據記錄。這種索引叫做聚集索引。因爲 InnoDB 的數據文件本身要按主鍵聚集,

 1 .InnoDB 要求表必須有主鍵,如果沒有顯式指定,則 MySQL系統會自動選擇一個可以唯一標識數據記錄的列作爲主鍵,如果不存在這種列,則MySQL 自動爲 InnoDB 表生成一個隱含字段作爲主鍵,類型爲長整形。

 同時,請儘量在 InnoDB 上採用自增字段做表的主鍵。因爲 InnoDB 數據文件本身是一棵B+Tree,非單調的主鍵會造成在插入新記錄時數據文件爲了維持 B+Tree 的特性而頻繁的分裂調整,十分低效,而使用自增字段作爲主鍵則是一個很好的選擇。如果表使用自增主鍵,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置,當一頁寫滿,就會自動開闢一個新的頁。如下圖所示:


MySQL索引實現原理分析

這樣就會形成一個緊湊的索引結構,近似順序填滿。由於每次插入時也不需要移動已有數據,因此效率很高,也不會增加很多開銷在維護索引上。

 2.第二個與 MyISAM 索引的不同是 InnoDB 的輔助索引 data 域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB 的所有輔助索引都引用主鍵作爲 data 域。
例如,圖 11 爲定義在 Col3 上的一個輔助索引:


MySQL索引實現原理分析
 

聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

 引申:爲什麼不建議使用過長的字段作爲主鍵?

 因爲所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。


聚簇索引與非聚簇索引 

InnoDB 使用的是聚簇索引, 將主鍵組織到一棵 B+樹中, 而行數據就儲存在葉子節點上, 若使用"where id = 14"這樣的條件查找主鍵, 則按照 B+樹的檢索算法即可查找到對應的葉節點, 之後獲得行數據。 若對 Name 列進行條件搜索, 則需要兩個步驟:
第一步在輔助索引 B+樹中檢索 Name, 到達其葉子節點獲取對應的主鍵。
第二步使用主鍵在主索引 B+樹種再執行一次 B+樹檢索操作, 最終到達葉子節點即可獲取整行數據。

MyISM 使用的是非聚簇索引, 非聚簇索引的兩棵 B+樹看上去沒什麼不同, 節點
的結構完全一致只是存儲的內容不同而已, 主鍵索引 B+樹的節點存儲了主鍵, 輔助鍵索引B+樹存儲了輔助鍵。 表數據存儲在獨立的地方, 這兩顆 B+樹的葉子節點都使用一個地址指向真正的表數據, 對於表數據來說, 這兩個鍵沒有任何差別。 由於索引樹是獨立的, 通過輔助鍵檢索無需訪問主鍵的索引樹。

爲了更形象說明這兩種索引的區別, 我們假想一個表如下圖存儲了 4 行數據。 其中Id 作爲主索引, Name 作爲輔助索引。 圖示清晰的顯示了聚簇索引和非聚簇索引的差異


MySQL索引實現原理分析

 

聯合索引及最左原則

聯合索引存儲數據結構圖:

最左原則:

例如聯合索引有三個索引字段(A,B,C)

查詢條件:

(A,,)---會使用索引

(A,B,)---會使用索引

(A,B,C)---會使用索引

(,B,C)---不會使用索引

(,,C)---不會使用索引

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