ORACLEBITMAP概要及简单实验

一、bitmap概要
纲要内容:
1.定义,什么是位图索引:就是用位图表示的索引,oracle对于选择度底的列的每个键值建立一个位图,位图中的每一位可能对应多个列,位图中位等于1表示特定的行含有此位图表示的键值。
2.查询,由于索引是位图,所以很多很多时候可以对这些索引中的位图进行位运算-(and 和 or),这样的速度明显比b树快(某些情况下)。由于位图索引可以存储null,所以可以直接通过位图索引计数(肯定是准确的)。后面提到的有点和位图的计算方式是直接相关的。
3.位图的优点(主要针对dw):
  •    减少即席查询的相应时间
  • 和其它类型索引比较,真正节约了索引数据空间
  • 即使在非常差的硬件上,也可能会有戏剧化的性能提升
  • 高效的并行DML和LOAD操作。
  • 生成索引的时候更高效,首先是不排序,其次是占用的空间少(索引空间)。
  • 可以通过位图索引直接计数。

4.位图索引的缺点(其它资料),也不好说是缺点

  •  不适合选择度底的列
  • 如果有比较频繁的insert,update等操作,可能导致性能很底下,因为更新索引用的是行锁(可能锁定多行),而不是排它锁。
  • 可能会溢出,索引数据块难于放下整个索引值,这导致低效。

二、主要了解以下位图原理图
oracle位图索引 - 我行我素 - 逝者如斯夫,不舍昼夜
 

 

需要注意的是,这只是个示意图,实际上每个位图的位数并非刚好等于记录数,而是会根据情况来分解,否则对于居多的数据而言,位图未免太大了。



三、bitmap原理解析

bitmap的存储结果相对来说,复杂一点。bitmap不存储rowid,rowid存储在每一个bitmap的头部,都存储了rowid的启示位置与结束位置。ORACLE通过自己的内部算 法,算出来相应的ROWID。
位图中的每一位,都记录是否有值。如表的记录是这样存储的:

row-value
male
female
female
male

那么对应的bitmap则是这样存储的:

rowid的启示位置与结束位置 rowid的启示位置与结束位置
male female
1 0
0 1
0 1
1 0

由 此可见,存储的空间大大的节省了,另外带来的收益就是扫描的BLOCK也大大减少了。

如果查找性别是male的数据,ORACLE只会去 搜索MALE这一列,然后是1的记录,返回即可。


如果是针对BITMAP字段本身做OR,AND这样的查询,那么ORACLE会在BITMAP索引内部,先做一次判断,找出符合结果的,再去计算ROWID,最后给出相应的VALUE,示意图如下:


bitmap join index
bitmap join index,它的特点就是将多张表的JOIN结果,存储在一个索引里面,然后使用BITMAP的形式进行存储。这个对于类似DW那样的多表join效率提高很明显。
做用3张表join来做测试如下,原来的SQL是这样的:
test@DB>select wt_cust.company_name,wt_cust.gmt_create

2   from wt_cust,wt_CUST_EXT ,wt_CUST_BOOK
3  where wt_cust.id=wt_CUST_EXT.Cust_Id
4  and wt_CUST_BOOK.Cust_Id=wt_cust.id;

58 rows selected.

Elapsed: 00:00:00.01

Execution Plan
———————————————————-

—————————————————————————————————-
| Id  | Operation                     | Name                          | Rows  | Bytes | Cost (%CPU)|
—————————————————————————————————-
|   0 | SELECT STATEMENT              |                               |    54 |  2484 |   179   (0)|
|   1 |  NESTED LOOPS                 |                               |    54 |  2484 |   179   (0)|
|   2 |   NESTED LOOPS                |                               |   177 |  7257 |   179   (0)|
|   3 |    INDEX FULL SCAN            | wt_CUST_BOOK_UK     |   177 |  1062 |     1   (0)|
|   4 |    TABLE ACCESS BY INDEX ROWID| wt_CUST             |     1 |    35 |     2   (0)|
|*  5 |     INDEX UNIQUE SCAN         | wt_CUST_PK          |     1 |       |     1   (0)|
|*  6 |   INDEX RANGE SCAN            | wt_CUST_EXT_CID_IND |     1 |     5 |     0   (0)|

—————————————————————————————————-

一 个3表join,效率很差。如果我们创建BITMAP JOIN INDEX则可以避免这种情况的发生:
test@DB>CREATE BITMAP INDEX cust_wt_test
2  ON     wt_cust(wt_cust.company_name)
3  FROM   wt_cust,wt_CUST_EXT ,wt_CUST_BOOK
4  WHERE  wt_cust.id=wt_CUST_EXT.Cust_Id
5  and wt_CUST_BOOK.Cust_Id=wt_cust.id
6  tablespace test_ind  ;

Index created.

Elapsed: 00:00:00.08
再来看看SQL的执行计划:
xx@DB>select  wt_cust.company_name,wt_cust.gmt_create
2   from wt_cust,wt_CUST_EXT ,wt_CUST_BOOK
3  where wt_cust.id=wt_CUST_EXT.Cust_Id
4  and wt_CUST_BOOK.Cust_Id=wt_cust.id;

58 rows selected.

Elapsed: 00:00:00.00

Execution Plan
———————————————————-

—————————————————————————————
| Id  | Operation                    | Name              | Rows  | Bytes | Cost (%CPU)|
—————————————————————————————
|   0 | SELECT STATEMENT             |                   |  1834K|    61M|   219K  (1)|
|   1 |  TABLE ACCESS BY INDEX ROWID | wt_CUST |  1834K|    61M|   219K  (1)|
|   2 |   BITMAP CONVERSION TO ROWIDS|                   |       |       |            |
|   3 |    BITMAP INDEX FULL SCAN    | CUST_WT_TEST      |       |       |            |
—————————————————————————————

请 着重注意红色部分。逻辑读大大降低!!



名称栏目:ORACLEBITMAP概要及简单实验
网页路径:http://ybzwz.com/article/jgijjh.html