我们目前大量使用的索引一般主要是B*Tree索引,在索引结构中存储着键值和键值的RowID,并且是一一对应的。而位图索引主要针对大量相同值的列而创建(例如:类别,操作员,部门ID,库房ID等),索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无.一个块可能指向的是几十甚至成百上千行数据的位置。这种方式存储数据,相对于B*Tree索引,占用的空间非常小,创建和使用非常快。
位图索引的目标是为用户提供指向包含特定键值(key value)的数据行的指针。在常规的索引中,Oracle
将各行的键值及与此键值对应的一组 ROWID
存储在一起,从而实现了上述目标。而在位图索引(bitmap index)中,只需存储每个键值的位图(bitmap),而非一组
ROWID。
位图(bitmap)中的每一位(bit)对应一个可能的
ROWID。如果某一位被置位(set),则表明着与此位对应的 ROWID
所指向的行中包含此位所代表的键值(key value)。Oracle
通过一个映射函数(mapping function)将位信息转化为实际的 ROWID,因此虽然位图索引(bitmap
index)内部的存储结构与常规索引不同,但她同样能实现常规索引的功能。当不同值的索引键的数量较少时,位图索引的存储效率相当高。
如果在 WHERE 子句内引用的多个列上都建有位图索引(bitmap
index),那么进行位图索引扫描时(bitmap indexing)可以将各个位图索引融合在一起。不满足全部条件的行可以被预先过滤掉。因此使用位图索引能够极大地提高查询的响应时间。
数据仓库应用中位图索引的优势
数据仓库应用(data warehousingapplication)的特点是数据量巨大,执行的多为自定义查询(ad
hoc query),且并发事务较少。这种环境下使用位图索引(bitmap index)具备如下优势:
· 能够减少大数据量自定义查询的响应时间
· 与其他索引技术相比能够节省大量存储空间
· 即使硬件配置较低也能显著提高性能
· 有利于并行 DML
和并行加载
为一个大表建立传统的平衡树索引(B-tree index)可能占用极大的存储空间,索引有可能比数据表还要大数倍。而一个位图索引(bitmap
index)所占的空间比被索引数据还要小得多。
位图索引(bitmap index)不适用于 OLTP
系统,因为这样的系统中存在大量对数据进行修改的并发事务。位图索引主要用于数据仓库系统中(data warehousing)的决策支持功能,在这种环境下用户对数据的操作主要是查询而非修改。
主要进行大于(greater than)或小于(less than)比较的列,不适宜使用位图索引(bitmap
index)。例如,WHERE 子句中常会将 salary
列和一个值进行比较,此时更适合使用平衡树索引(B-tree index)。位图索引适用于等值查询,尤其是存在 AND,OR,和 NOT 等逻辑操作符的组合时。
位图索引(bitmap index)是集成在 Oracle
的优化器(optimizer)和执行引擎(execution engine)之中的。位图索引也能够和
Oracle 中的其他执行方法(execution method)无缝地组合。例如,优化器可以在利用一个表的位图索引和另一个表的平衡树索引(B-tree index)对这两张表进行哈希连接(hash
join)。优化器能够在位图索引及其他可用的访问方法(例如常规的平衡树索引,或全表扫描(full table scan))中选择效率最高的方式,同时考虑是否适合使用并行执行。
位图索引(bitmap index)如同常规索引一样,可以结合并行查询(parallel
query)和并行 DML(parallel DML)一起工作。建立于分区表(partitioned
table)的位图索引必须为本地索引(local index)。Oracle
还支持并行地创建位图索引,以及创建复合位图索引。
基数
在基数(cardinality)小的列上建立位图索引(bitmap index)效果最好。所谓某列的基数小(low
cardinality)是指此列中所有不相同的值的个数要小于总行数。如果某列中所有不相同的值的个数占总行数的比例小于 1%,或某列中值的重复数量在 100
个以上,那么就可以考虑在此列上建立位图索引。即便某列的基数较上述标准稍大,或值的重复数量较上述标准稍小,如果在一个查询的 WHERE 子句中需要引用此列定义复杂的条件,也可以考虑在此列上建立位图索引。
例如,一个表包含一百万行数据,其中的一列包含一万个不相同的值,就可以考虑在此列上创建位图索引(bitmap index)。此列上位图索引的查询性能将超过平衡树索引(B-tree
index),当此列与其他列作为组合条件时效果尤为明显。
平衡树索引(B-tree index)适用于高基数的数据,即数据的可能值很多,例如CUSTOMER_NAME 或 PHONE_NUMBER 列。在有些情况下,平衡树索引所需的存储空间可能比被索引数据还要大。如果使用得当,位图索引将远远小于同等情况下的平衡树索引。
对于自定义查询(ad hoc query)或相似的应用,使用位图索引(bitmap
index)能够显著地提高查询性能。查询的 WHERE 子句中的 AND 和 OR 条件直接对位图(bitmap)进行布尔运算(Boolean
operation)得到一个位图结果集(resulting bitmap),而无需将所有的位图转换为 ROWID。如果布尔操作后的结果集较小,那么查询就能够迅速得到结果,而无需进行全表扫描(full
table scan)。
位图索引和空值
与其他大多数索引不同,位图索引(bitmap index)可以包含键值(key
value)为 NULL 的行。将键值为空的行进行索引对有些 SQL
语句是有用处的,例如包含 COUNT 聚合函数的查询。
分区表上的位图索引
用户可以在分区表(partitioned table)上创建位图索引(bitmap
index)。唯一的限制是位图索引对分区表来说必须是本地的(local),而不能是全局索引(global index)。只有非分区表才能使用全局位图索引。
位图连接索引
除了建立在单个表之上的位图索引(bitmap index),用户还可以创建位图连接索引(bitmap
join index),此种索引是为了连接(join)两个或多个数据表而建的。位图连接索引(bitmap join index)可以预先将有连接关系的数据进行保存,且所需的存储空间较小。对于一个表的某列的每个值,位图连接索引为其保存其他表中与此值有连接关系的数据行的
rowid。在数据仓库环境中,连接关系通常是维表(dimension table)中的主键(primary key)与事实表(fact
table)中的外键(foreign key)进行等值内连接(equi-inner join)。
物化连接视图(materialized joinview)也是一种预先将连接物化的方法,但与之相比位图连接索引(bitmap
join index)所需的存储空间更少。因为物化连接视图不会压缩事实表(fact table)中的 rowid。
位图索引的优缺点
优点:OLAP
例如报表类数据库重复率高的数据特定类型的查询例如count、or、and等逻辑操作因为只需要进行位运算即可得到我们需要的结果
缺点:不适合重复率低的字段,还有经常DML操作(insert,update,delete),因为位图索引的锁代价极高,修改一个位图索引段影响整个位图段,例如修改
一个键值,会影响同键值的多行,所以对于OLTP
系统位图索引可能不是最合适的,甚至是会对系统系统造成严重危害的;(BDC平台,主入口表的状态尝试修改为位图索引,导致当时入库数据堵塞严重)。
总而言之,在平台中如果要使用位图索引,一定要仔细验证使用前后的性能情况。
有部分文字和内容来自互联网