首先要知道Hash索引和B+樹索引的底層實現原理:
hash索引底層就是hash表,進行查詢時,調用一次hash函數就可以獲取到相應的鍵值,之后進行回表查詢獲得實際數據.
B+樹底層實現原理是多路平衡查找樹,對於每一次的查詢都是從根節點出發,查詢到葉子節點方可以獲得所查鍵值,然后查詢判斷是否需要回表查詢.
區別:
hash索引
1:hash索引進行等值查詢更快(一般情況下)但是卻無法進行范圍查詢.因為在hash索引中經過hash函數建立索引之后,索引的順序與原順序無法保持一致,不能支持范圍查詢.
2:hash索引不支持模糊查詢以及多列索引的最左前綴匹配,因為hash函數的不可預測,eg:AAAA和AAAAB的索引沒有相關性.
3:hash索引任何時候都避免不了回表查詢數據.
4:hash索引雖然在等值上查詢叫快,但是不穩定,性能不可預測,當某個鍵值存在大量重復的時候,發生hash碰撞,此時查詢效率可能極差.
5:hash索引不支持使用索引進行排序,因為hash函數的不可預測.
B+樹
1:B+樹的所有節點皆遵循(左節點小於父節點,右節點大於父節點,多叉樹也類似)自然支持范圍查詢.
2:在符合某些條件(聚簇索引,覆蓋索引等)的時候可以只通過索引完成查詢.不需要回表查詢.
3:查詢效率比較穩定,對於查詢都是從根節點到葉子節點,且樹的高度較低.
結論
大多數情況下,直接選擇B+樹索引可以獲得穩定且較好的查詢速度,而不需要使用Hash索引.
上面提到了B+樹在滿足聚簇索引和覆蓋索引的時候不需要回表查詢數據,什么是聚簇索引呢?
聚簇索引:表數據按照索引的順序來儲存的,也就是說索引項的順序與表中記錄的物理順序一致.在B+樹的索引中葉子節點可能儲存了當前的key值,也可能儲存了當前的key值以及整行的數據,在一張表上最多只能創建一個聚簇索引,因為真實數據的物理順序只有一種.
非聚簇索引:表數據存儲順序與索引順序無關,對於非聚簇索引,葉子節點包含索引字段值及指向數據頁數據行的邏輯指針.
聚簇索引和非聚簇索引總結: 聚簇索引是一種稀疏索引,數據頁的上一級的索引頁儲存的是頁指針,而不是行指針,而非聚簇索引,則是密集索引,在數據頁的上一級索引頁它為每一個數據行存儲一條索引記錄.
在InnoDB中,只有主鍵索引是聚簇索引,如果沒有主鍵,則挑選一個唯一鍵建立聚簇索引,如果沒有唯一鍵,則隱式的生成一個鍵建立索引.
當查詢使用聚簇索引時,在對應的葉子節點,可以獲得到整行數據,因此不用再次進行回表查詢.
非聚簇索引一定會回表查詢嗎?
不一定,這涉及到查詢語句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必在進行回表查詢了.
eg:假設我們在員工表的年齡上建立了索引,那么當進行select age from employee where age<20的查詢時,在索引的葉子節點上,已經包含了age信息,不會再次進行回表查詢.