位圖索引,數據庫索引淺淺的學習


            摘自http://www.cnblogs.com/LBSer/p/3322630.html

 

位圖(BitMap)索引

  前段時間聽同事分享,偶爾講起Oracle數據庫的位圖索引,頓時大感興趣。說來慚愧,在這之前對位圖索引一無所知,因此趁此機會寫篇博文介紹下位圖索引。

1. 案例

  有張表名為table的表,由三列組成,分別是姓名、性別和婚姻狀況,其中性別只有男和女兩項,婚姻狀況由已婚、未婚、離婚這三項,該表共有100w個記錄。現在有這樣的查詢:     select * from table where Gender=‘男’ and Marital=“未婚”;

姓名(Name)

性別(Gender)

婚姻狀況(Marital)

張三

已婚

李四

已婚

王五

未婚

趙六

離婚

孫七

未婚

...

...

...

 

1)不使用索引

  不使用索引時,數據庫只能一行行掃描所有記錄,然后判斷該記錄是否滿足查詢條件。

2)B樹索引

  對於性別,可取值的范圍只有'男','女',並且男和女可能各站該表的50%的數據,這時添加B樹索引還是需要取出一半的數據, 因此完全沒有必要。相反,如果某個字段的取值范圍很廣,幾乎沒有重復,比如身份證號,此時使用B樹索引較為合適。事實上,當取出的行數據占用表中大部分的數據時,即使添加了B樹索引,數據庫如oracle、mysql也不會使用B樹索引,很有可能還是一行行全部掃描。

2. 位圖索引出馬

如果用戶查詢的列的基數非常的小, 即只有的幾個固定值,如性別、婚姻狀況、行政區等等。要為這些基數值比較小的列建索引,就需要建立位圖索引。

對於性別這個列,位圖索引形成兩個向量,男向量為10100...,向量的每一位表示該行是否是男,如果是則位1,否為0,同理,女向量位01011。

RowId

1

2

3

4

5

...

1

0

1

0

0

 

0

1

0

1

1

 

 

  對於婚姻狀況這一列,位圖索引生成三個向量,已婚為11000...,未婚為00100...,離婚為00010...。

RowId

1

2

3

4

5

...

已婚

1

1

0

0

0

 

未婚

0

0

1

0

1

 

離婚

0

0

0

1

0

 

   當我們使用查詢語句“select * from table where Gender=‘男’ and Marital=“未婚”;”的時候 首先取出男向量10100...,然后取出未婚向量00100...,將兩個向量做and操作,這時生成新向量00100...,可以發現第三位為1,表示該表的第三行數據就是我們需要查詢的結果。 

RowId

1

2

3

4

5

1

0

1

0

0

and

 

 

 

 

 

未婚

0

0

1

0

1

結果

0

0

1

0

0

3.位圖索引的適用條件

  上面講了,位圖索引適合只有幾個固定值的列,如性別、婚姻狀況、行政區等等,而身份證號這種類型不適合用位圖索引。

  此外,位圖索引適合靜態數據,而不適合索引頻繁更新的列。舉個例子,有這樣一個字段busy,記錄各個機器的繁忙與否,當機器忙碌時,busy為1,當機器不忙碌時,busy為0。

  這個時候有人會說使用位圖索引,因為busy只有兩個值。好,我們使用位圖索引索引busy字段!假設用戶A使用update更新某個機器的busy值,比如update table set table.busy=1 where rowid=100;,但還沒有commit,而用戶B也使用update更新另一個機器的busy值,update table set table.busy=1 where rowid=12; 這個時候用戶B怎么也更新不了,需要等待用戶A commit。

  原因:用戶A更新了某個機器的busy值為1,會導致所有busy為1的機器的位圖向量發生改變,因此數據庫會將busy=1的所有行鎖定,只有commit之后才解鎖。

 

 

以下內容轉載自:https://blog.csdn.net/pzqingchong/article/details/50971854

當前測試的版本是Mysql 5.5.25只有BTree和Hash兩種索引類型,默認為BTree。Oracle或其他類型數據庫中會有Bitmap索引(位圖索引),這里作為比較也一起提供。

 

BTree索引

BTree(多路搜索樹,並不是二叉的)是一種常見的數據結構。使用BTree結構可以顯著減少定位記錄時所經歷的中間過程,從而加快存取速度。按照翻譯,B 通常認為是Balance的簡稱。這個數據結構一般用於數據庫的索引,綜合效率較高。——百度百科

不適合:

  • 單列索引的列不能包含null的記錄,復合索引的各個列不能包含同時為null的記錄,否則會全表掃描;
  • 不適合鍵值較少的列(重復數據較多的列);
  • 前導模糊查詢不能利用索引(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位圖索引

 就是用位圖表示的索引,對列的每個鍵值建立一個位圖。相對於BTree索引,占用的空間非常小,創建和使用非常快。位圖索引由於只存儲鍵值的起止Rowid和位圖,占用的空間非常少。如test表中有state這樣一列,10行數據如下:

10    20    30    20    10    30    10    30    20    30

那么會建立三個位圖,如下:

BLOCK1    KEY=10  1    0    0    0    1    0    1    0    0    0   
BLOCK2    KEY=20  1    0    0    0    1    0    1    0    0    0 
BLOCK3    KEY=30  1    0    0    0    1    0    1    0    0    0

適合

  • 適合決策支持系統;
  • 當select count(XX) 時,可以直接訪問索引中一個位圖就快速得出統計數據;
  • 當根據鍵值做and,or或 in(x,y,..)查詢時,直接用索引的位圖進行或運算,快速得出結果行數據。

不適合

    • 不適合鍵值較多的列(重復值較少的列);
    • 不適合update、insert、delete頻繁的列,代價很高。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM