最近在项目中遇到一个情况,SQL 的 where 条件设计某一列为人名信息,分布规律较差,筛选率不高,因此选择了位图索引进行创建。语句类似为:
create bitmap index "DM_TEST" on "SYSDBA"."TEST("NAME") storage(initial 1,next 1,minextents 1);
创建完成后,使用语句查询,速度从原来的 2S 降低到 20MS 效果非常显著。
但好景不长,在接下来的测试过程中发现了奇怪的现象,对系统进行 INSERT 场景的测试过程中,出现了死锁情况。而时间节点正好是创建为这个位图索引的时间点。于是将位图索引去掉后,发现死锁的情况消失。判定问题就在位图索引这里。
这是为什么呢?首先我们来看下位图索引的原理:
位图索引就是用位图表示的索引,对列的每个键值建立一个位图。相对于 BTree 索引,占用的空间非常小,创建和使用非常快。位图索引由于只存储键值的起止 Rowid 和位图,占用的空间非常少。如 test 表中有 state 这样一列,10 行数据如下:
那么会建立三个位图,如下:
可以想象到,当对一条数据进行增删改后,上述三个 KEY 对应的值都会做修改。如果开始描述的问题,当有大概 500 个人名的表中做大量的 INSERT,那么一次就会对 KEY 造成 500 次的数据修改。批量时就是成500*N 倍修改,数据量可想而知!
因此建议位图索引的使用范围为:
不建议使用的范围为:
1.不适合键值较多的列(重复值较少的列);
2.不适合 update、insert、delete 频繁的列,代价很高。
文章
阅读量
获赞