雜湊索引和Btree索引的比較

2022-01-21 20:05:09 字數 3310 閱讀 9020

索引是幫助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本身由於其特殊性,也帶來了很多限制和弊端:

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

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

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

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

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

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

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

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

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

1. hash索引查詢資料基本上能一次定位資料,當然有大量碰撞的話效能也會下降。而btree索引就得在節點上挨著查詢了,很明顯在資料精確查詢方面hash索引的效率是要高於btree的;

2. 那麼不精確查詢呢,也很明顯,因為hash演算法是基於等值計算的,所以對於「like」等範圍查詢hash索引無效,不支援;

3. 對於btree支援的聯合索引的最優字首,hash也是無法支援的,聯合索引中的字段要麼全用要麼全不用。提起最優字首居然都泛起迷糊了,看來有時候放空得太厲害;

4. hash不支援索引排序,索引值和計算出來的hash值大小並不一定一致。

索引是幫助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本身由於其特殊性,也帶來了很多限制和弊端:

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

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

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

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

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

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

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

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

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

1. hash索引查詢資料基本上能一次定位資料,當然有大量碰撞的話效能也會下降。而btree索引就得在節點上挨著查詢了,很明顯在資料精確查詢方面hash索引的效率是要高於btree的;

2. 那麼不精確查詢呢,也很明顯,因為hash演算法是基於等值計算的,所以對於「like」等範圍查詢hash索引無效,不支援;

3. 對於btree支援的聯合索引的最優字首,hash也是無法支援的,聯合索引中的字段要麼全用要麼全不用。提起最優字首居然都泛起迷糊了,看來有時候放空得太厲害;

4. hash不支援索引排序,索引值和計算出來的hash值大小並不一定一致。

**:

mysql之BTree索引 和 雜湊索引

排好序的快速查詢資料結構。索引會影響where後面的查詢,和order by 後面的排序。基於雜湊表實現,只有精確匹配索引所有列的查詢才有效。對於每一行資料,儲存引擎都會對所有的索引列計算乙個雜湊碼 hash code 並且hash索引將所有的雜湊碼儲存在索引中,同時在索引表中儲存指向每個資料行的指...

Hash索引和BTree索引

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

Hash索引和BTree索引

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