oracle 位图索引

位图索引是一种使用 位图的特殊数据库索引。主要针对大量相同值的列而创建,比如(性别、婚配等字段可选值很少的字段创建位图索引);

位图索引非常适合于决策支持系统(Decision Support System,DSS)和数据仓库,它们不应该用于通过事务处理应用程序访问的表。它们可以使用较少到中等基数(不同值的数量)的列访问非常大的表;

索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,

位置编码中的每一位表示键值对应的数据行的有无.一个块可能指向的是几十甚至成百上千行数据的位置.
这种方式存储数据,相对于B*Tree索引,占用的空间非常小,创建和使用非常快
当根据键值查询时,可以根据起始Rowid和位图状态,快速定位数据.
创建语法很简单,就是在普通索引创建的语法中index前加关键字 bitmap即可,例如:
 
位图索引的特点:
1.Bitmap索引的存储空间
相对于B*Tree索引, 位图索引由于只存储键值的起止Rowid和 位图,占用的空间非常少.
bitmap的空间占用主要跟以下4个因素相关:
a.表的总记录数
b.索引列的键值多少,列的不同值越少,所需的位图就越少.
c.操作的类型,批量插入比单条插入所需的位图要少得多,8i,9i下是这样的,10G则没有这种区别,详见后面的分析.
d.索引列相同键值的物理分布,8i,9i中,不同块上的数据,相同的键值,会建立不同的位图行(段)来表示
注:本文提到的8i,9i,10g,我试验的环境是8.1.7,9.2.0.5,10.2
2.Bitmap索引创建的速度
位图索引创建时不需要排序,并且按位存储,所需的空间也少.
B*Tree索引则在创建时需要排序,定位等操作,速度要慢得多.
3.Bitmap索引允许键值为空
B*Tree索引由于不记录 空值,当基于is null的查询时,会使用 全表扫描,
而对 位图索引列进行is null查询时,则可以使用索引.
4.Bitmap索引对表记录的高效访问
当使用count(XX),可以直接访问索引就快速得出统计数据.
当根据 位图索引的列进行and,or或 in(x,y,..)查询时,直接用索引的位图进行或运算,在访问数据之前可事先过滤数据.
5.Bitmap索引对批量 DML操作只需进行一次索引
由于通过位图反映数据情况,批量操作时对索引的更新速度比B*Tree索引一行一行的处理快得多.
6.Bitmap索引的锁机制
对于B*Tree索引,insert操作不会锁定其它会话的DML操作.
位图索引,由于用位图反映数据,不同会话更新相同键值的同一位图段,insert、update、delete相互操作都会发锁定。
 
 
 

技巧:

对于有较低基数的列需要使用位图索引。性别列就是这样一个例子,它有两个可能值:男或女(基数仅为2)。位图对于低基数(少量的不同值)列来说非常快,这是因为索引的尺寸相对于B树索引来说小了很多。因为这些索引是低基数的B树索引,

所以非常小,因此您可以经常检索表中超过半数的行,并且仍使用位图索引。

当大多数条目不会向位图添加新的值时,位图索引在批处理(单用户)操作中加载表(插入操作)方面通常要比B树做得好。当多个会话同时向表中插入行时不应该使用位图索引,在大多数事务处理应用程序中都会发生这种情况。

技巧:

如果要查询位图索引列表,可以在USER _INDEXES视图中查询index_type列。

建议不要在一些联机事务处理(OLTP)应用程序中使用位图索引。B树索引的索引值中包含ROWID,这样Oracle就可以在行级别上锁定索引。

位图索引存储为压缩的索引值,其中包含了一定范围的ROWID,因此Oracle必须针对一个给定值锁定所有范围内的ROWID。这种锁定类型可能在某些DML语句中造成死锁。SELECT语句不会受到这种锁定问题的影响。

位图索引有很多限制,如下所示:

    • 基于规则的优化器不会考虑位图索引。
    • 当执行ALTER TABLE语句并修改包含有位图索引的列时,会使位图索引失效。
    • 位图索引不包含任何列数据,并且不能用于任何类型的完整性检查。
    • 位图索引不能被声明为唯一索引。
    • 位图索引的最大长度为30。

技巧:

不要在繁重的OLTP环境中使用位图索引

 

猜你喜欢

转载自www.cnblogs.com/leewi/p/10276537.html