通过以下实验,来验证Bitmap位图索引较之普通的B-Tree索引锁的“高昂代价”。位图索引会带来“位图段级锁”,实际使用过程一定要充分了解不同索引带来的锁代价情况。
1)在表t_bitmap上创建位图索引
SYS@ORA11GR2>create table t_bitmap (id number (10),name varchar2(10),sex varchar2(1));
Table created.
SYS@ORA11GR2>create bitmap index t_bitmap_idx on t_bitmap(sex);
Index created.
2)在表t_btree上创建普通B-Tree索引
SYS@ORA11GR2>create table t_btree (id number(10),name varchar2(10),sex varchar2(1));
Table created.
SYS@ORA11GR2>create index t_btree_idx on t_btree(sex);
Index created.
1)初始化数据t_bitmap表数据
SYS@ORA11GR2>insert into t_bitmap values(1,'WANG','M');
1 row created.
SYS@ORA11GR2>insert into t_bitmap values(2,'chen','F');
1 row created.
2)初始化数据t_btree表数据
SYS@ORA11GR2>insert into t_btree values(1,'WANG','M');
1 row created.
SYS@ORA11GR2>insert into t_btree values(2,'chen','F');
1 row created.
SYS@ORA11GR2>commit;
Commit complete.
3)查看初始化之后的结果
SYS@ORA11GR2>select * from t_bitmap;
ID NAME S
---------- ---------- -
1 WANG M
2 chen F
SYS@ORA11GR2>select * from t_btree;
ID NAME S
---------- ---------- -
1 WANG M
2 chen F
第一个session中的插入后不要提交
SYS@ORA11GR2>insert into t_btree values (3,'ANDY','M');
1 row created.
第二个session中插入同样的状态数据,可以看到,插入、修改和删除均能够成功完成!
SYS@ORA11GR2>insert into t_btree values(4,'tut','M');
1 row created.
SYS@ORA11GR2>update t_btree set sex='M' where id=2;
1 row updated.
1)第一个session中的插入后不要提交
SYS@ORA11GR2>insert into t_bitmap values(3,'ANDY','M');
1 row created.
2)第二个session中对男孩数据进行处理,可以看到,只要操作信息中涉及到位图索引列的插入、修改和删除均无法完成!!
(1)插入测试
当插入数据涉及位图索引列“sex”字段时,是无法完成的。
SYS@ORA11GR2>insert into t_bitmap values(4,'tut','M');
问题出现了:出现了“锁等待”停滞不动的现象!
当插入数据未涉及位图索引列“sex”字段时,是可以完成的。
SYS@ORA11GR2>insert into t_bitmap(id,name) values(4,'tut');
1 row created.
SYS@ORA11GR2>commit;
Commit complete.
(2)更新测试
此时第二个会话的测试数据内容如下:
当更新位图索引列“sex”字段值为“M”时,是无法完成的。此时成功,是因为第一行数据的sex值本身就是“M”。
SYS@ORA11GR2>update t_bitmap set sex='M' where id=1;
1 row updated.
SYS@ORA11GR2>update t_bitmap set sex='M' where id=2;
问题出现了:出现了“锁等待”停滞不动的现象!
SYS@ORA11GR2>update t_bitmap set sex='M' where id=4;
问题出现了:出现了“锁等待”停滞不动的现象!
另外,特别注意一下,如果更新的列不是位图索引对应的列,将不会受位图段级索引锁的限制。
如下所示。
SYS@ORA11GR2>update t_bitmap set name='xu' where id=2;
1 row updated.
SYS@ORA11GR2>select * from t_bitmap;
ID NAME S
---------- ---------- -
1 WANG M
2 xu F
4 tut
(3)删除测试
SYS@ORA11GR2>delete from t_bitmap where id=1;
出现了“锁等待”停滞不动的现象!
SYS@ORA11GR2>delete from t_bitmap;
问题出现了:出现了“锁等待”停滞不动的现象!
位图索引最好用于低cardinality列(即列的唯一值除以行数为一个很小的值,接近零),例如上面的“性别”列,列值有“M”,“F”两种。在这个基本原则的基础上,要认真考虑包含位图索引的表的操作特点,如果是并发操作高的系统,不适合使用位图索引!
转自:【索引】Bitmap位图索引与普通的B-Tree索引锁的比较