天天看點

【Bitmap Index】B-Tree索引與Bitmap位圖索引的鎖代價比較研究

通過以下實驗,來驗證Bitmap位圖索引較之普通的B-Tree索引鎖的“高昂代價”。位圖索引會帶來“位圖段級鎖”,實際使用過程一定要充分了解不同索引帶來的鎖代價情況。

1.為比較差別,建立兩種索引類型的測試表

1)在表t_bitmap上建立位圖索引

SEC@ora11g> create table t_bitmap (id number(10), name varchar2(10),sex varchar2(1));

Table created.

SEC@ora11g> create bitmap index t_bitmap_idx on t_bitmap(sex);

Index created.

2)在表t_btree上建立普通B-Tree索引

SEC@ora11g> create table t_btree (id number(10), name varchar2(10), sex varchar2(1));

SEC@ora11g> create index t_btree_idx on t_btree(sex);

2.每張表中初始化兩條資料:“一個男孩”和“一個女孩”

注釋:

M - Male - 表示男孩;

F - Femail - 表示女孩。

1)初始化資料t_btree表資料

SEC@ora11g> insert into t_btree values (1, 'Secoooler', 'M');

1 row created.

SEC@ora11g> insert into t_btree values (2, 'Anna','F');

2)初始化資料t_bitmap表資料

SEC@ora11g> insert into t_bitmap values (1, 'Secoooler', 'M');

SEC@ora11g> insert into t_bitmap values (2, 'Anna','F');

SEC@ora11g> commit;

Commit complete.

3)檢視初始化之後的結果

(1)t_btree表中包含兩條資料

SEC@ora11g> select * from t_btree;

        ID NAME       S

---------- ---------- -

         1 Secoooler  M

         2 Anna       F

(2)t_bitmap表中包含兩條資料

SEC@ora11g> select * from t_bitmap;

3.在兩個不同的session中,對具有普通B-Tree索引表t_btree示範插入、修改和删除“男孩”資料

第一個session中的插入後不要送出

SEC@ora11g> insert into t_btree values (3, 'Andy', 'M');

第二個session中插入同樣的狀态資料,可以看到,插入、修改和删除均能夠成功完成

SEC@ora11g> insert into t_btree values (4, 'Tutu', 'M');

SEC@ora11g> update t_btree set sex='M' where id=2;

1 row updated.

SEC@ora11g> delete from t_btree;

2 rows deleted.

4.在兩個不同的session中,對具有Bitmap位圖索引表t_bitmap示範插入、修改和删除“男孩”資料

1)第一個session中的插入後不要送出

SEC@ora11g> insert into t_bitmap values (3, 'Andy', 'M');

2)第二個session中對男孩資料進行處理,可以看到,隻要操作資訊中涉及到位圖索引列的插入、修改和删除均無法完成!!

(1)插入測試

當插入資料涉及位圖索引列“sex”字段時,是無法完成的。

SEC@ora11g> insert into t_bitmap values (4, 'Tutu', 'M');

問題出現了:出現了“鎖等待”停滞不動的現象!

當插入資料未涉及位圖索引列“sex”字段時,是可以完成的。

SEC@ora11g> insert into t_bitmap(id,name) values (4, 'Tutu');

(2)更新測試

此時第二個會話的測試資料内容如下。

         4 Tutu

當更新位圖索引列“sex”字段值為“M”時,是無法完成的。

SEC@ora11g> update t_bitmap set sex='M' where id=1;

此時成功,是因為第一行資料的sex值本身就是“M”。

SEC@ora11g> update t_bitmap set sex='M' where id=2;

SEC@ora11g> update t_bitmap set sex='M' where id=4;

另外,特别注意一下,如果更新的列不是位圖索引對應的列,将不會受位圖段級索引鎖的限制。如下所示。

SEC@ora11g> update t_bitmap set name='Xu' where id=2;

(3)删除測試

當删除的資料包含位圖索引列“sex”字段值為“M”時,是無法完成的。

SEC@ora11g> delete from t_bitmap where id=1;

當删除表中的所有資料時,同樣的道理,也是不能删除的。

SEC@ora11g> delete from t_bitmap;

5.小結

  本文以對資料本身沖擊力最小的插入動作為例,示範了B-Tree和Bitmap索引的鎖代價。對于B-Tree索引來說,插入動作不影響其他會話的DML操作;但是,對于Bitmap索引來說,由于是索引段級鎖,會導緻與操作列值相關的内容被鎖定(文中提到的“M”資訊)。進一步,對于更新動作來說,

  産生上面現象的原因:

  位圖索引被存儲為壓縮的索引值,其中包含了一個範圍内的ROWID,是以ORACLE必須針對一個給定值鎖定所有範圍内的ROWID,不支援行級别的鎖定。

  換一種描述方法:使用位圖索引時,一個鍵指向多行(成百上千),如果更新一個位圖索引鍵,會同時将其他行對應位圖索引字段進行鎖定!

  較之B-Tree索引優點:

  位圖以一種壓縮格式存放,是以占用的磁盤空間比B-Tree索引要小得多

  較之B-Tree索引缺點:

  這種鎖定的代價很高,會導緻一些DML語句出現“鎖等待”,嚴重影響插入、更新和删除的效率,對于高并發的系統不适用。

  位圖索引使用原則:

  位圖索引主要用于決策支援系統或靜态資料,不支援索引行級鎖定。

  位圖索引最好用于低cardinality列(即列的唯一值除以行數為一個很小的值,接近零),例如上面的“性别”列,列值有“M”,“F”兩種。在這個基本原則的基礎上,要認真考慮包含位圖索引的表的操作特點,如果是并發操作高的系統,不适合使用位圖索引!

轉:http://blog.itpub.net/519536/viewspace-611296/

本文轉自 張沖andy 部落格園部落格,原文連結: http://www.cnblogs.com/andy6/p/5766934.html  ,如需轉載請自行聯系原作者