关于oracle中位图索引的探讨:概念、原理、优缺点

FenggFocusOracle 2019-03-08

概述

oracle索引主要分为以下几种:

1. b-tree索引

Oracle数据库中最常见的索引类型是b-tree索引,也就是B-树索引,以其同名的计算科学结构命名。CREATE INDEX语句时,默认就是在创建b-tree索引。没有特别规定可用于任何情况。

2. 位图索引(bitmap index)

位图索引特定于该列只有几个枚举值的情况,比如性别字段,标示字段比如只有0和1的情况。

3. 基于函数的索引

比如经常对某个字段做查询的时候是带函数操作的,那么此时建一个函数索引就有价值了。

4. 分区索引和全局索引

这2个是用于分区表的时候。前者是分区内索引,后者是全表索引

5. 反向索引(REVERSE)

这个索引不常见,但是特定情况特别有效,比如一个varchar(5)位字段(员工编号)含值(10001,10002,10033,10005,10016..)

这种情况默认索引分布过于密集,不能利用好服务器的并行

但是反向之后10001,20001,33001,50001,61001就有了一个很好的分布,能高效的利用好并行运算。

6.HASH索引

HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。使用HASH索引必须要使用HASH集群。

索引这么多,重点还是把握b-tree索引和位图索引,今天先介绍下oracle的位图索引。

关于oracle中位图索引的探讨:概念、原理、优缺点


什么是位图索引

简单点就是用位图表示的索引,oracle对于选择度底的列的每个键值建立一个位图,位图中的每一位可能对应多个列,位图中位等于1表示特定的行含有此位图表示的键值。

我们目前大量使用的索引一般主要是B-Tree索引,在索引结构中存储着键值和键值的RowID,并且是一一对应的,而位图索引主要针对大量相同值的列而创建(例如:类别,操作员,部门ID,库房ID等),索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无.一个位图索引块可能指向的是几十甚至成百上千行数据的位置。

创建语法:

create bitmap index idx_bm_emp1_deptno on emp1(deptno);

可以使用如下的 SQL 语句查询数据库中的所有位图索引:

SELECT * FROM DBA_INDEXES D WHERE D.INDEX_TYPE='BITMAP';

关于oracle中位图索引的探讨:概念、原理、优缺点


查询原理

由于索引是位图,所以很多时候可以对这些索引中的位图进行位运算-(and 和 or),这样的速度明显比b树快(某些情况下)。由于位图索引可以存储null,所以可以直接通过位图索引计数(肯定是准确的)。

假设某个表T里所有的记录在列C1上只具有三个值:01、02和03。在表T的C1列上创建位图索引以后,则叶子节点的内容如图9-14所示。可以看到,位图索引只有三个索引条目,也就是每个C1列的值对应一个索引条目。位图索引条目上还包含表里第一条记录所对应的ROWID以及最后一条记录所对应的ROWID。索引条目的最后一部分则是由多个bit位所组成的bitmap,每个bit位就对应一条记录。

关于oracle中位图索引的探讨:概念、原理、优缺点

位图索引

当发出where c1='01'这样的SQL语句时,oracle会去搜索01所在的索引条目,然后扫描该索引条目中的bitmap里所有的bit位。第一个bit位为 1,则说明第一条记录上的C1值为01,于是返回第一条记录所在的ROWID(根据该索引条目里记录的start ROWID加上行号得到该记录所在的ROWID)。第二个bit位为0,则说明第二条记录上的C1值不为01,依此类推。另外,如果索引列为空,也会在位 图索引里记录,也就是将对应的bit位设置为0即可。

如果索引列上不同值的个数比较少的时候,比如对于性别列(男或女)等,则使用位图索引会比较好,因为它对空间的占用非常少(因为都是用bit位来表示表里 的数据行),从而在扫描索引的时候,扫描的索引块的个数也比较少。

可以试想一下,如果在列的不同值非常多的列上,比如主键列上,创建位图索引,则产生的索 引条目就等于表里记录的条数,同时每个索引条目里的bitmap里,只有一个1,其它都是0。这样还不如B树索引的效率高。 如果被索引的列经常被 更新的话,则不适合使用位图索引。因为当更新位图所在的列时,由于要在不同的索引条目之间修改bit位,比如将第一条记录从01变为02,则必须将01所 在的索引条目的第一个bit位改为0,再将02所在的索引条目的第一个bit位改为1。

因此,在更新索引条目的过程中,会锁定位图索引里多个索引条目。也就是同时只能有一个用户能够更新表T,从而降低了并发性。


位图的优点(主要针对dw)

1、减少即席查询的相应时间

2、和其它类型索引比较,真正节约了索引数据空间

3、即使在非常差的硬件上,也可能会有戏剧化的性能提升

4、高效的并行DML和LOAD操作。

5、生成索引的时候更高效,首先是不排序,其次是占用的空间少(索引空间)。

6、可以通过位图索引直接计数。


位图索引的缺点

1、不适合选择度低的列

2、如果有比较频繁的insert,update等操作,可能导致性能很底下,因为更新索引用的是行锁(可能锁定多行),而不是排它锁。

3、可能会溢出,索引数据块难于放下整个索引值,这有可能导致低效。


总结:

位图索引是为数据仓库(也就是查询环境设计的),位图索引特别不适合OLTP系统,位图索引不适合与dml频繁的环境,位图索引适用于DSS系统,位图索引不适合频繁修改的系统,弊端是严重影响并发性,因为update索引列值的时候,会锁定新值和旧值指向的所有数据行,所以使用位图索引需慎重。

后面会分享更多DBA和devops方面的内容,感兴趣的朋友可以关注下!

关于oracle中位图索引的探讨:概念、原理、优缺点

相关推荐