bitmap位图索引简介

Oracle数据库的位图索引(Bitmap Index)确实是针对那些数值稀疏(low-cardinality,低基数)的字段,但是还应记住的一点是,它是针对那些值不经常改变的字段的。在实际应用中,如果某个字段的值需要频繁更新,那么就不适合在它上面创建位图索引。在位图索引中,如果你更新或插入其中一条数值为N的记录,那么相应表中数值为N的记录(可能成百上千条)全部被Oracle锁定,这就意味着其它用户不能同时更新这些数值为N的记录,其它用户必须要等第一个用户提交后,才能获得锁,更新或插入数据。


bitmap主要用于数据仓库,table有大量的数据并且列上基数很小(一般是column的distinct values占rows总数的1%以下,或重复出现超过100次以上,Oracle建议此时才可以把该column列为创建bitmap index的侯选字段),同时,还由于数据仓库上并行访问的事务非常少。bitmap index并不适用于OLTP业务,OLTP一般都是有大量的并发事务来修改同样的数据。bitmap主要就是设计来为数据仓库服务的,即应用于低基数超 级大数据量查询服务,而且只用在where clause里包含and ,or,not,或equality queries(比如在and和or条件的查询,在把bit转换成rowid以前,就能很快的得到相应的boolean操作)。


bitmap index方法从Oracle 7.3版本开始就加到oracle数据库里了。现在只在企业版和个人版里有,在标准版里没有。



bitmap的创建方法为,为table column里的每个key value(唯一值)创建一个bitmap,用来记录table里这些具有相同key value的rows的物理地址,bitmap里每个bit可能就对应了某个具有相同key value的row的物理地址(如果bit被set了,那么该bit对应的rowid的row就记录了key value,map函数能把一个bit的位置转换到实际的rowid),如果key value个数很少(即基数很小,比如该colun只记录性别,那么就只有男,女两种情况),用bitmap的index方法是可以节省很多磁盘空间的,同时同一个table里多个column所创建的不同的bitmap之间,在实际access table前,能有效的进行merge,这也会很大的提高执行性能。



bitmap主要用于数据仓库,table有大量的数据并且列上基数很小(一般是column的distinct values占rows总数的1%以下,或重复出现超过100次以上,Oracle建议此时才可以把该column列为创建bitmap index的侯选字段),同时,还由于数据仓库上并行访问的事务非常少。bitmap index并不适用于OLTP业务,OLTP一般都是有大量的并发事务来修改同样的数据。bitmap主要就是设计来为数据仓库服务的,即应用于低基数超级大数据量查询服务,而且只用在where clause里包含and ,or,not,或equality queries(比如在and和or条件的查询,在把bit转换成rowid以前,就能很快的得到相应的boolean操作)。



bitmap index 非常不利于DML操作,每次DML操作,bitmap segment就要被更新一次。每个key value的压缩bitmap被Oracle内部组织成一个或多个bitmap segment,每个bitmap segment一般要占一个block的一大半,加锁的间隔尺寸也是一个同样的bitmap segment,这样在同时执行DML语句的环境下,对性能影响非常大,如果发生很多的DML操作,就会导致bitmap index的size增大和降低查询性能,改变这种状况,一般使用alter index ... rebuild语句来compact index和恢复性能。一般的B-tree index,一个index entry只包含一个rowid,(所以B-tree index就会有很多个index entry),所以当一个index entry被lock时,也只是一条row被lock而已,但bitmap index,一个entry可能包含的是一个rowid的范围,(所以bitmap index只有很少的index entry),如果这个bitmap index entry被lock了(Oracle不能lock单个bit,只能以index entry为单位lock),那么那些与被bitmap index entry包含的rowid范围对应的rows都会被lock。这样就降低了应用的并发性(因为一个用户在更改bitmap index entry的时候,其他用户对该entry的更改只能被lock在外面等候,这样很明显的影响并发性,如同串行操作一样,在更改操作完成前,具有old value的index key entry和具有new value的index key entry都不可用)。如果一个bitmap segment的rowid增加了,也就是说,相应的并发性就降低了。(lock对DML操作和OLTP环境影响非常大,但对于查询性能没有影响)。更新 bitmap index是资源消费,即成本很大的操作。bitmap index对于固定长度的column比可变长度的column工作的更好。

 

 

位图索引占用的空间很大.一个466万行记录的只有两个字段的表,占用空间约 88M,在该两个字段上建有一个位图索引,这个位图索引占用空间约168M
查看各个表(包括索引)占用空间大小的sql:
Select Segment_Name,Sum(bytes)/1024/1024 From User_Extents Group By Segment_Name

你可能感兴趣的:(bitmap位图索引简介)