【MySQL索引】Hash索引與B-Tree索引 介紹及區別

【摘要】 php

      這是從《MySQL性能調優與架構設計》第六章摘錄的一些知識點。 算法

【主題】 數據庫

  • Hash索引
  • B-Tree索引

【內容】 數據結構

1. Hash索引 架構

      Hash 索引結構的特殊性,其檢索效率很是高,索引的檢索能夠一次定位,不像B-Tree 索引須要從根節點到枝節點,最後才能訪問到頁節點這樣屢次的IO訪問,因此 Hash 索引的查詢效率要遠高於 B-Tree 索引。
      可能不少人又有疑問了,既然 Hash 索引的效率要比 B-Tree 高不少,爲何你們不都用 Hash 索引而還要使用 B-Tree 索引呢?任何事物都是有兩面性的,Hash 索引也同樣,雖然 Hash 索引效率高,可是 Hash 索引自己因爲其特殊性也帶來了不少限制和弊端,主要有如下這些。
性能

 

(1)Hash 索引僅僅能知足"=","IN"和"<=>"查詢,不能使用範圍查詢。
     因爲 Hash 索引比較的是進行 Hash 運算以後的 Hash 值,因此它只能用於等值的過濾,不能用於基於範圍的過濾,由於通過相應的 Hash 算法處理以後的 Hash 值的大小關係,並不能保證和Hash運算前徹底同樣。
ui

(2)Hash 索引沒法被用來避免數據的排序操做。
     因爲 Hash 索引中存放的是通過 Hash 計算以後的 Hash 值,並且Hash值的大小關係並不必定和 Hash 運算前的鍵值徹底同樣,因此數據庫沒法利用索引的數據來避免任何排序運算;
spa

(3)Hash 索引不能利用部分索引鍵查詢。
     對於組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合併後再一塊兒計算 Hash 值,而不是單獨計算 Hash 值,因此經過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也沒法被利用。
架構設計

(4)Hash 索引在任什麼時候候都不能避免表掃描。
     前面已經知道,Hash 索引是將索引鍵經過 Hash 運算以後,將 Hash運算結果的 Hash 值和所對應的行指針信息存放於一個 Hash 表中,因爲不一樣索引鍵存在相同 Hash 值,因此即便取知足某個 Hash 鍵值的數據的記錄條數,也沒法從 Hash 索引中直接完成查詢,仍是要經過訪問表中的實際數據進行相應的比較,並獲得相應的結果。
設計

(5)Hash 索引遇到大量Hash值相等的狀況後性能並不必定就會比B-Tree索引高。
     對於選擇性比較低的索引鍵,若是建立 Hash 索引,那麼將會存在大量記錄指針信息存於同一個 Hash 值相關聯。這樣要定位某一條記錄時就會很是麻煩,會浪費屢次表數據的訪問,而形成總體性能低下。

 

2. B-Tree索引

      B-Tree 索引是 MySQL 數據庫中使用最爲頻繁的索引類型,除了 Archive 存儲引擎以外的其餘全部的存儲引擎都支持 B-Tree 索引。不只僅在 MySQL 中是如此,實際上在其餘的不少數據庫管理系統中B-Tree 索引也一樣是做爲最主要的索引類型,這主要是由於 B-Tree 索引的存儲結構在數據庫的數據檢
索中有很是優異的表現。
      通常來講, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的結構來存儲的,也就 是全部實際須要的數據都存放於 Tree 的 Leaf Node ,並且到任何一個 Leaf Node 的最短路徑的長度都是徹底相同的,因此咱們你們都稱之爲 B-Tree 索引固然,可能各類數據庫(或 MySQL 的各類存儲引擎)在存放本身的 B-Tree 索引的時候會對存儲結構稍做改造。如 Innodb 存儲引擎的 B-Tree 索引實際使用的存儲結構其實是 B+Tree ,也就是在 B-Tree 數據結構的基礎上作了很小的改造,在每個
Leaf Node 上面出了存放索引鍵的相關信息以外,還存儲了指向與該 Leaf Node 相鄰的後一個 LeafNode 的指針信息,這主要是爲了加快檢索多個相鄰 Leaf Node 的效率考慮。
      在 Innodb 存儲引擎中,存在兩種不一樣形式的索引,一種是 Cluster 形式的主鍵索引( Primary Key ),另一種則是和其餘存儲引擎(如 MyISAM 存儲引擎)存放形式基本相同的普通 B-Tree 索引,這種索引在 Innodb 存儲引擎中被稱爲 Secondary Index 。下面咱們經過圖示來針對這兩種索引的存放
形式作一個比較。

QQ截圖未命名

      圖示中左邊爲 Clustered 形式存放的 Primary Key ,右側則爲普通的 B-Tree 索引。兩種 Root Node 和 Branch Nodes 方面都仍是徹底同樣的。而 Leaf Nodes 就出現差別了。在 Prim中, Leaf Nodes 存放的是表的實際數據,不只僅包括主鍵字段的數據,還包括其餘字段的數據據以主鍵值有序的排列。而 Secondary Index 則和其餘普通的 B-Tree 索引沒有太大的差別,Leaf Nodes 出了存放索引鍵 的相關信息外,還存放了 Innodb 的主鍵值。

      因此,在 Innodb 中若是經過主鍵來訪問數據效率是很是高的,而若是是經過 Secondary Index 來訪問數據的話, Innodb 首先經過 Secondary Index 的相關信息,經過相應的索引鍵檢索到 Leaf Node以後,須要再經過 Leaf Node 中存放的主鍵值再經過主鍵索引來獲取相應的數據行。MyISAM 存儲引擎的主鍵索引和非主鍵索引差異很小,只不過是主鍵索引的索引鍵是一個惟一且非空 的鍵而已。並且 MyISAM 存儲引擎的索引和 Innodb 的 Secondary Index 的存儲結構也基本相同,主要的區別只是 MyISAM 存儲引擎在 Leaf Nodes 上面出了存放索引鍵信息以外,再存放能直接定位到 MyISAM 數據文件中相應的數據行的信息(如 Row Number ),但並不會存放主鍵的鍵值信息。

相關文章
相關標籤/搜索