1. 程式人生 > >Hash索引和BTree索引區別

Hash索引和BTree索引區別

索引是幫助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,sex),會先檢查name欄位,如果name欄位相同再去檢查後兩個欄位。

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

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

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

2、不能過度索引:在修改表內容的時候,索引必須更新或者重構,所以索引過多時,會消耗更多的時間。

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

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

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

相關推薦

Hash索引BTree索引區別

索引是幫助mysql獲取資料的資料結構。最常見的索引是Btree索引和Hash索引。 不同的引擎對於索引有不同的支援:Innodb和MyISAM預設的索引是Btree索引;而Mermory預設的索引是Hash索引。 我們在mysql中常用兩種索引演算法BTr

Mysql索引---Hash索引Btree索引區別

索引名 hash Btree 支援最左字首匹配原則? 不支援,只有索引的全部欄位都用上才會匹配到 支援,用上索引的第一個欄位就可以匹配索引 MyISAM和InnoDB是否支援? 不支

hash索引btree索引區別

可 能很多人又有疑問了,既然 Hash 索引的效率要比 B-Tree 高很多,為什麼大家不都用 Hash 索引而還要使用 B-Tree 索引呢?任何事物都是有兩面性的,Hash 索引也一樣,雖然 Hash 索引效率高,但是 Hash 索引本身由於其特殊性也帶來了很多限制和弊端,主要有以下這些。 (1)Has

(ainusers原創)Hash索引BTree索引

注: Innodb和myisam預設的索引是Btree索引 Hash索引(類比於拼音查詢漢字)   BTree(類比於偏旁查詢漢字) 區別(瞭解Innodb和myisam主要還應該從區別開始) 1.主要區別在於:Hash不能用於範圍查詢 2.檢索效率遠高於BTree

mysql的hash索引btree索引

mysql的hash索引和btree索引 hash 索引有著與剛才所討論特點的相比截然不同的特點: Hash 索引只能夠用於使用 = 或者 <=> 運算子的相等比較(但是速度更快)。Hash 索引不能夠用於諸如 < 等用於查詢一個範圍值的比較運算子。依賴於這種單值查詢

Hash索引BTree索引

至於Btree索引,它是以B+樹為儲存結構實現的。 但是Btree索引的儲存結構在Innodb和MyISAM中有很大區別。 在MyISAM中,我們如果要對某張表的某列建立Btree索引的話,如圖: 所以我們經常會說MyISAM中資料檔案和索引檔案是分開的。 因此MyISAM的索引方式也稱

mysql索引型別Normal,Unique,Full Text區別以及索引方法btree索引hash區別

一.mysql索引型別Normal,Unique,Full Text區別 (1)Normal: 表示普通索引,大多數情況下都可以使用 (2)Unique: 約束唯一標識資料庫表中的每一條記錄,即在單表中不能用每條記錄是唯一的(例如身份證就是唯一的),Unique(要求列唯一)和Primary K

索引原理-btree索引hash索引區別

基於 信息 一起 特殊性 hash算法 一個 即使 數據 就會   btree索引與hash索引的區別,之前不清楚,mark一下。   Hash索引結構的特殊性,其檢索效率非常高,索引的檢索可以一次定位,不像B-Tree索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多

數據庫索引BTree索引Hash索引

就是 strong 存儲引擎 sql 基於 條件 mysql b+ tree 索引   索引是為了方便查找我們所需要的數據。 mysql支持的索引數據類型 B-Tree索引的特點 B-Tree索引以B+Tree(樹)的結構存儲數據。 B-Tree索引能夠加快

單列索引聯合索引區別

csdn 搜索 fontsize 添加 lai water 描述 plain 版本 原文鏈接:https://blog.csdn.net/Abysscarry/article/details/80792876 一、聯合索引測試 註:Mysql版本為 5.7.20 我們

普通索引唯一索引區別、性能差異,以及其他索引簡介

整數 排列 唯一索引 同名 關聯 超過 結果 其它 加載 唯一索引和普通索引使用的結構都是B-tree,執行時間復雜度都是O(log n)。 1、普通索引  普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。因此,應該只為那些最經常出現在查

唯一索引普通索引區別

一、背景介紹 索引用來快速地尋找那些具有特定值的記錄,如果沒有索引,執行查詢時Mysql必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄,表裡面的記錄數量越多,這個操作的代價就越高,如果作為搜尋條件的列上已經建立了索引,mysql無需掃描任何記錄即可迅速得到目標記錄所在的位置。如

普通索引唯一索引區別

轉自:https://blog.csdn.net/u014071328/article/details/78780683 唯一索引和普通索引使用的結構都是B-tree,執行時間複雜度都是O(log n)。 1、普通索引   普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快

SAP裡主索引二級索引區別

更多內容關注公眾號:SAP Technical 透明表索引有兩種:分別是主索引和二級索引。 主索引是在我們建立表啟用後由系統自動建立的,這個我們不能修改;二級索引可以我們自己建立。 主索引是表的主鍵,二級索引可以根據你自己需要用到表的任何欄位的組合來建立。 在使用二級索引時,WHERE

聯合索引單個索引區別

聯合索引和單個索引的區別: 如果我們建立了(area, age,salary)的複合索引,那麼其實相當於建立了: (area,age,salary),(area,age)、(area)三個索引,這被稱為最佳左字首 特性。因此我們在建立複合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。

多個單列索引聯合索引區別詳解

背景: 為了提高資料庫效率,建索引是家常便飯;那麼當查詢條件為2個及以上時,我們是建立多個單列索引還是建立一個聯合索引好呢?他們之間的區別是什麼?哪個效率高呢?我在這裡詳細測試分析下。 一、聯合索引測試 注:Mysql版本為 5.7.20 建立測試表

【轉】Mysql學習-索引總結(B-treehash、主鍵索引、唯一索引、普通索引、全文索引組合索引)

常用的兩種索引結構:B-tree和HASH B-tree   B-tree索引能夠加快訪問資料的速度,因為儲存引擎不再需要經行全表掃描來獲取需要的資料,取而代之的是從根節點開始搜尋。根節點的槽中存放了指向子節點的指標,儲存引擎根據這些指標向下查詢。通常比較節點頁的值和要查詢的值可以找

索引二級索引區別,並建立一個二級索引

透明表索引有兩種:分別是主索引和二級索引。 主索引是在我們建立表啟用後由系統自動建立的,這個我們不能修改;二級索引可以我們自己建立。 主索引是表的主鍵,二級索引可以根據你自己需要用到表的任何欄位的組

mysql單個索引聯合索引區別

聯合索引和單個索引的區別: 如果我們建立了(area, age,salary)的複合索引,那麼其實相當於建立了: (area,age,salary),(area,age)、(area)三個索引,這被稱為最佳左字首 特性。因此我們在建立複合索引時應該將最常用作限制條件的列

普通索引唯一索引區別、效能差異,以及其他索引簡介

今天在我的虛擬機器中佈置了環境,測試抓圖如下: 抓的這幾個都是第一次執行的,刷了幾次後,取平均值,效率大致相同,而且如果在一個列上同時建唯一索引和普通索引的話,mysql會自動選擇唯一索引。 谷歌一下: 唯一索引和普通索引使用的結構都是B-tree,執行時間複