Hash索引和BTree索引區別

2021-09-05 10:52:45 字數 2988 閱讀 2709

索引是幫助mysql獲取資料的資料結構。最常見的索引是btree索引和hash索引。

不同的引擎對於索引有不同的支援:innodb和myisam預設的索引是btree索引;而mermory預設的索引是hash索引。

我們在mysql中常用兩種索引演算法btree和hash,兩種演算法檢索方式不一樣,對查詢的作用也不一樣。

一、btree

btree索引是最常用的mysql資料庫索引演算法,因為它不僅可以被用在=,>,>=,<,<=和between這些比較操作符上,而且還可以用於like操作符,只要它的查詢條件是乙個不以萬用字元開頭的常量,例如:

select * from user where name like 『jack%』;

select * from user where name like 『jac%k%』;

如果一萬用字元開頭,或者沒有使用常量,則不會使用索引,例如:

select * from user where name like 『%jack』;

select * from user where name like simply_name;

二、hash

hash索引只能用於對等比較,例如=,<=>(相當於=)操作符。由於是一次定位資料,不像btree索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次io訪問,所以檢索效率遠高於btree索引。

但為什麼我們使用btree比使用hash多呢?主要hash本身由於其特殊性,也帶來了很多限制和弊端:

1. hash索引僅僅能滿足「=」,「in」,「<=>」查詢,不能使用範圍查詢。

2. 聯合索引中,hash索引不能利用部分索引鍵查詢。

對於聯合索引中的多個列,hash是要麼全部使用,要麼全部不使用,並不支援btree支援的聯合索引的最優字首,也就是聯合索引的前面乙個或幾個索引鍵進行查詢時,hash索引無法被利用。

3. hash索引無法避免資料的排序操作

由於hash索引中存放的是經過hash計算之後的hash值,而且hash值的大小關係並不一定和hash運算前的鍵值完全一樣,所以資料庫無法利用索引的資料來避免任何排序運算。

4. hash索引任何時候都不能避免表掃瞄

hash索引是將索引鍵通過hash運算之後,將hash運算結果的hash值和所對應的行指標資訊存放於乙個hash表中,由於不同索引鍵存在相同hash值,所以即使滿足某個hash鍵值的資料的記錄條數,也無法從hash索引中直接完成查詢,還是要通過訪問表中的實際資料進行比較,並得到相應的結果。

5. hash索引遇到大量hash值相等的情況後效能並不一定會比btree高

對於選擇性比較低的索引鍵,如果建立hash索引,那麼將會存在大量記錄指標資訊存於同乙個hash值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表資料訪問,而造成整體效能底下。

hash索引

所謂hash索引,當我們要給某張表某列增加索引時,將這張表的這一列進行雜湊演算法計算,得到雜湊值,排序在雜湊陣列上。所以hash索引可以一次定位,其效率很高,而btree索引需要經過多次的磁碟io,但是innodb和myisam之所以沒有採用它,是因為它存在著好多缺點:

1、因為hash索引比較的是經過hash計算的值,所以只能進行等式比較,不能用於範圍查詢

1、每次都要全表掃瞄

2、由於雜湊值是按照順序排列的,但是雜湊值對映的真正資料在雜湊表中就不一定按照順序排列,所以無法利用hash索引來加速任何排序操作

3、不能用部分索引鍵來搜尋,因為組合索引在計算雜湊值的時候是一起計算的。

4、當雜湊值大量重複且資料量非常大時,其檢索效率並沒有btree索引高的。

btree索引

至於btree索引,它是以b+樹為儲存結構實現的。

但是btree索引的儲存結構在innodb和myisam中有很大區別。

在myisam中,我們如果要對某張表的某列建立btree索引的話,如圖:

所以我們經常會說myisam中資料檔案和索引檔案是分開的。

因此myisam的索引方式也稱為非聚集,innodb的索引方式成為聚集索引。

至於輔助索引,類似於主索引,唯一區別就是主索引上的值不能重複,而輔助索引可以重複。

因此當我們根據btree索引去搜尋的時候,若key存在,在data域找到其位址,然後根據位址去表中查詢資料記錄。

至於innodb它跟上面又有很大不同,它的葉子節點儲存的並不是表的位址,而是資料

我們可以看到這裡並沒有將位址放入葉子節點,而是直接放入了對應的資料,這也就是我們平常說到的,innodb的索引檔案就是資料檔案,

那麼對於innodb的輔助索引結構跟主索引也相差很多,如圖:

我們可以發現,這裡葉子節點儲存的是主鍵的資訊,所以我們在利用輔助索引的時候,檢索到主鍵資訊,然後再通過主鍵去主索引中定位表中的資料,這就可以說明innodb中主鍵之所以不宜用過長的字段,由於所有的輔助索引都包含主索引,所以很容易讓輔助索引變得龐大。

我們還可以發現:在innodb中盡量使用自增的主鍵,這樣每次增加資料時只需要在後面新增即可,非單調的主鍵在插入時會需要維持b+tree特性而進行**調整,十分低效。

btree索引中的最左匹配原則:

btree是按照從左到右的順序來建立搜尋樹的。比如索引是(name,age,***),會先檢查name欄位,如果name欄位相同再去檢查後兩個字段。

所以當傳進來的是後兩個欄位的資料(age,***),因為建立搜尋樹的時候是按照第乙個字段建立的,所以必須根據name欄位才能知道下乙個欄位去**查詢。

所以傳進來的是(name,***)時,首先會根據name指定搜尋方向,但是第二個字段缺失,所以將name欄位正確的都找到後,然後才會去匹配***的資料。

建立索引的規則:

1、利用最左字首:mysql會一直向右查詢直到遇到範圍操作(>,<,like、between)就停止匹配。比如a=1 and b=2 and c>3 and d=6;此時如果建立了(a,b,c,d)索引,那麼後面的d索引是完全沒有用到,當換成了(a,b,d,c)就可以用到。

3、盡量擴充套件索引而不要新建索引

4、最適合的索引的列是出現在where子句中的列或連線子句中指定的列。

5、不同值較少的列不必要建立索引(性別)。

Hash索引和BTree索引

索引是幫助mysql獲取資料的資料結構。最常見的索引是btree索引和hash索引。不同的引擎對於索引有不同的支援 innodb和myisam預設的索引是 btree索引 而mermory預設的索引是hash索引。所謂hash索引,當我們要給某張表某列增加索引時,將這張表的這一列進行雜湊演算法計算,...

Hash索引和BTree索引

索引是幫助mysql獲取資料的資料結構。最常見的索引是btree索引和hash索引。不同的引擎對於索引有不同的支援 innodb和myisam預設的索引是 btree索引 而mermory預設的索引是hash索引。所謂hash索引,當我們要給某張表某列增加索引時,將這張表的這一列進行雜湊演算法計算,...

Btree索引,Hash索引

1.什麼是btree索引,hash索引 備註 在mysql 文件裡,實際上是把 b 樹索引寫成了 btree 在 mysql 裡常用的索引資料結構有 b 樹索引 和雜湊索引 兩種。2.btree索引,hash索引特點 b 樹索引是乙個平衡的多叉樹,同層級的節點間有指標相互鏈結,基於索引的順序掃瞄時,...