本文转载的http://www.cn blogs.com/lbs er/p/3322630.html位图(BitMap )索引在这段时间内一直在收听同事共享,但有时会在Oracle数据库中导入位图虽然很不好意思,但是到目前为止我对位图索引一无所知,所以我想借此机会写一篇博文介绍位图索引。
1 .案例中有由姓名、性别、婚姻状况三列组成的table表。 其中,性别只有男女两种,婚姻状况为已婚、未婚、离婚三种,此表共有100w的记录。 目前,select * from table where Gender=‘男’and marital=“未婚”;
http://www.Sina.com/http://www.Sina.com /
http://www.Sina.com/http://www.Sina.com /
http://www.Sina.com/http://www.Sina.com /
zydnht/p男
已婚人士
ajdlr/p女
已婚人士
王五
男人
未婚
兴奋的蚂蚁
女人
离婚
完美手机
女人
未婚
姓名
(Name)
性别
1 )不使用索引
如果不使用索引,数据库只能在一行中扫描所有记录,并确定该记录是否满足查询条件。
2 ) b树索引
按性别来看,可取的范围只有“男”、“女”,而且男女可能各站都有本表50%的数据。 在这种情况下,添加b树索引仍然需要提取一半的数据,因此完全不需要。 相反,如果某个字段的值范围很大,几乎没有身份证号码等重复项,则最好使用b树索引。 事实上,如果检索的行数据占表中的大部分数据,则即使添加了b树索引,oracle和mysql等数据库也很可能不会使用b树索引,而是扫描所有行。
2 .位图索引参选用户查询的列基数非常小,即只有一些固定值,如性别、婚姻状况、行政区等。 要为这些基础值小的列创建索引,必须创建位图索引。
对于一列性别,位图索引形成两个向量,男性向量为10100 .其中每一位表示该行是否为男性,否则为比特1,否则为0。 同样地,它是女性向量比特01011。
(Gender)
婚姻状况
(Marital)
...
...
...
RowId
男人
1
0
1
0
0
女人
0
1
0
1
1
对于婚姻状况这一列,位图索引生成三个向量:已婚11000 .未婚00100 .离婚00010 .
1
2
g>23
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之后才解锁。
转载源地址:http://www.cnblogs.com/LBSer转载于:https://www.cnblogs.com/outmanxiaozhou/p/10136897.html