位图索引

常规的B树索引对包含每行记录的ROWID与索引键值。位图索引不会直接存储ROWID,每个不同的键值都有一个位图,这就是为什么创建位图索引的列要有较少的distinct值的原因。位图中的每一位映射到一个可能的ROWID,位图中每一位的特定值代表是否存在有价值的记录,因此位图中存储了关于特定行和相关的ROWID。如果ROWID的值与条件匹配在rowid的位置存储“1”,不匹配存储“0”。Oracle会压
缩位图的存储。

创建位图索引
create bitmap index index_name on table_name(columns);Oracle将创建一系列的位图,列中每个特定值都会被使用。例如,如果创建位图索引的列有’East’和’Central’两个值,那么将会为’East’和’Central’创建位图。如果是复合位图索引,那么位图将是由
任何一组可能的排列值组成。

位图索引的使用
1.列有较低的基数:较少的distinct值
2.位图索引对于包含较长where子句或聚合查询(包含sum,count或其它聚合函数)的ad hoc查询很有帮助
3.表行记录很多(比如有1,000,000行记录有10,000个distinct值)
4.对于表执行ad hoc查询很频繁
5.数据仓库环境(DSS系统)。位图索引对于联机事务处理(OLTP)不适用这是由于位图索引的锁机制造成的,只锁定单个位图的位置是不能实现的。能够被锁定的最小位图量是一个位图段,它的大小可以达到数据块的一半。改变一行记录会造成一个位图段被锁定,而实际上只改变了一行记录。当有许多update,insert或delete语句被执行时,影响会更明显。在数据仓库中当数据批量加载或更新时这种影响不是问题。
6.位图连接索引是9中引入的,通过连接可以避免在连接条件上预先创建位图索引的必要

位图索引的限制
1.不能用于RBO
2.不能用于分区表的全局索引
3.不支持联机创建或重建
4.对位图索引使用直接路径加载,”SORTED_INDEX”标记不能应用
5.位图索引不能用于引用完整性
6.位图索引不能定义为UNIQUE
7.在9i之前,当创建一个索引组织表时不能使用位图索引,从9i开始才支持。
8.对域索引不能使用bitmap

与B树索引相比的优点
1.减少了许多ad hoc查询的响应时间
2.大幅减少了存储空间
a)有少量distinct值的单列位图索引
如果位图索引是创建在一个唯一键上,它将比常规B树索引使用的空间更多。然后,如果列中有成百上千个重复值时,位图索引通常要比常规B树索引所使用的空间减少25%。位图是以压缩的格式来进行存储的。

b)在多列上创建位图索引
位图索引与B树索引相比可以大量节省存储空间。在数据库中只包含B树索引,必须对查询中所使用的列进行预测并对这些列创建一个复合B树索引。多列复合B树索引不仅需要大量的空间,还要进行排序。对于在(marital_status,region,gender)上创建的B树索引,对于只访问REGION与DENDER在前导列marital_status有太多distinct值的情况下是没有用的。为了使用索引,必须对这些列的其它组合方
式创建索引。简单来说,对于三个低基数列就有6种组合的B树索引。必须对创建那种组合的B树索引和需要的存储空间进行考虑。B树索引可以解决这种问题。位图索引可以在查询执行时进行有效的组合,因此三个小的单列位图索引可以完成6个三列B树索引所做的事情。

3.非常影响并行DML与加载
位图索引适合数据仓库程序但不适合有高并发insert,update与delete系统。在数据仓库环境中,数据通常是批量插入和更新的。索引维护操作直到每个DML操作结束才执行。

4.包含null值的记录

位图索引的使用技巧
1.对所有可能的列定义not null约束将会减少存储空间,因为这将不会为null值创建位图。
2.使用固定长度的数据类型将会减少存储空间
3.增加create_bitmap_area_size参数可以提高查询处理速度。这个参数决定了对位图创建所分配的内存大小。这个参数决定了用于合并位图从范围扫描索引执行检索所使用的内存。

位图索引的例子
MARITAL_ STATUS REGION GENDER INCOME_LEVEL
————— ——– ——- ————
101 single east male bracket_1
102 married central female bracket_4
103 married west female bracket_2
104 divorced west male bracket_4
105 single central female bracket_2
106 married central female bracket_3

国灰marital_status,region,gender与income_level都是低基数列(对于matil_status与region只有三个可能的值,对于gender有两个可能的值,income_level列有四个可能的值)。在这些列上适合创建位图索引。在customer#上不适合创建位图索引,因为这个列有高基数。相反,一个唯一的B树索引将会提供最好的检索效率。

在这个例子中,region列的位图索引,它包括三个单独的位图
REGION=’east’ REGION=’central’ REGION=’west’ ## CUSTOMER #
1 0 0 < == 101 0 1 0 <== 102 0 0 1 <== 103 0 0 1 <== 104 0 1 0 <== 105 0 1 0 <== 106 位图中的每个条目或位关联到customer表中的单独一行记录。每一位的值依赖于表中相关行的值。例如,位REGION='east'包含一个1作为它的第一位。这是因为region='east'在表customer中的第一行存在。region='east'在其它行位为0,是因为其它行的region列不包含'east'。 下面的查询是要查询在中部或西部地区有多少已婚的客户: SELECT COUNT(*) FROM CUSTOMER WHERE MARITAL_STATUS = 'married' AND REGION IN ('central','west'); 位图索引可以非常有效的通过仅仅计算结果位图中为1的数量来进行处理。 status = 'married' region = 'central' region = 'west' 0 0 0 1 1 0 1 0 1 0 AND ( 0 OR 1 ) 0 1 0 1 1 0 0 0 0 1 1 1 ==> 2nd row
= 1 1 1 ==> 3rd row
0 AND 1 = 0
0 1 0
1 1 1 ==> last row

One thought on “位图索引

发表评论

电子邮件地址不会被公开。