1. 程式人生 > >資料庫索引演算法的優缺點

資料庫索引演算法的優缺點

當前測試的版本是Mysql 5.5.25只有BTree和Hash兩種索引型別,預設為BTree。Oracle或其他型別資料庫中會有Bitmap索引(點陣圖索引),這裡作為比較也一起提供。

 BTree索引

BTree(多路搜尋樹,並不是二叉的)是一種常見的資料結構。使用BTree結構可以顯著減少定位記錄時所經歷的中間過程,從而加快存取速度。按照翻譯,B 通常認為是Balance的簡稱。這個資料結構一般用於資料庫的索引,綜合效率較高。邏輯結構為一顆N叉平衡樹,每列中distinct  key 都對應一個 RIDs(Row IDentifiers)陣列。樹狀結構適合頻繁的更新操作,適用於事物型資料庫。

不適合:

  • 單列索引的列不能包含null的記錄,複合索引的各個列不能包含同時為null的記錄,否則會全表掃描;
  • 不適合鍵值較少的列(重複資料較多的列),即低基數情況,索引結構空間冗餘,B-Tree樹上會存在大量相同鍵值的葉子節點,造成嚴重的空間和I/O掃描浪費;
  • N叉平衡樹的結構會隨著記錄的增多而膨脹。
  • 單一索引路徑選擇問題,即SQL條件中包含多列時,即時每個列對應一個索引,在執行中也只能沿著一個索引的執行路徑, 而其它列之能作為篩選條件。
  • 前導模糊查詢不能利用索引(like '%XX'或者like '%XX%')

Hash雜湊索引

Hash雜湊索引是根據HASH演算法來構建的索引。雖然 Hash 索引效率高,但是 Hash 索引本身由於其特殊性也帶來了很多限制和弊端,主要有以下這些。

適合:

  • 精確查詢非常快(包括= <> 和in),其檢索效率非常高,索引的檢索可以一次定位,不像BTree 索引需要從根節點到枝節點,所以 Hash 索引的查詢效率要遠高於 B-Tree 索引。

不適合:

  • 不適合模糊查詢和範圍查詢(包括like,>,<,between……and等),由於 Hash 索引比較的是進行 Hash 運算之後的 Hash 值,所以它只能用於等值的過濾,不能用於基於範圍的過濾,因為經過相應的 Hash 演算法處理之後的 Hash 值的大小關係,並不能保證和Hash運算前完全一樣;
  • 不適合排序,資料庫無法利用索引的資料來提升排序效能,同樣是因為Hash值的大小不確定;
  • 複合索引不能利用部分索引欄位查詢,Hash 索引在計算 Hash 值的時候是組合索引鍵合併後再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。
  • 同樣不適合鍵值較少的列(重複值較多的列);

Bitmap點陣圖索引

 就是用位圖表示的索引,對列的每個鍵值建立一個位圖,即每列中的distinct key都對應一bit序列。相對於BTree索引,佔用的空間非常小,建立和使用非常快。點陣圖索引由於只儲存鍵值的起止Rowid和點陣圖,佔用的空間非常少。

下圖是點陣圖索引的一個直觀描述。其中,Identifier列是每一行的唯一標識,HasInternet是索引列,那麼右側的Bitmaps下方的兩列Y和N則表示左側所對應的bitmap索引。 
點陣圖索引邏輯檢視

適合

  • 適合決策支援系統,資料倉庫,OLAP類分析場景,圖資料庫;
  • 當select count(XX) 時,可以直接訪問索引中一個位圖就快速得出統計資料;
  • 當根據鍵值做and,or或 in(x,y,..)查詢時,直接用索引的點陣圖進行或運算,快速得出結果行資料。
  • 利用計算機硬體對按位操作(AND/OR/XOR)的強有力的支援,從而使單列內部的按位操作可以有效的轉化為按位邏輯操作。
  • 多列之間的結果聚合也可以有效的轉化為按位邏輯操作。
  • 適合只讀,較少更新或者追加的資料集上的查詢操作。

不適合

  • 不適合鍵值較多的列(重複值較少的列);
  • 不適合update、insert、delete頻繁的列,代價很高。
  • 更新操作慢,由於更新操作的鎖只能有單使用者獲取,並且需要同時鎖住很多索引,故併發效能較差。