Welcome 微信登录

首页 / 数据库 / MySQL / Oracle Bitmap Index

Oracle的bitmap索引,我们用的很少。在我们的常理认识当中,我们用的最多就是类似性别,类型这种属性的字段,因为他们字段的种类很少。其实 BITMAP还是有很多优势以及一些特性的。 首先在传统的INDEX里,我们在索引的存储上,一般是分为:header+index length+index value+rowid组成。如图:bitmap的存储结果相对来说,复杂一点。 bitmap 不存储rowid。那么rowid存储在哪里呢?答:每一个bitmap的头部,都存储了rowid的启示位置与结束位置。ORACLE通过自己的内部算 法,算出来相应的ROWID。
位图中的每一位,都记录是否有值。
如表的记录是这样存储的:
row-value
male
female
female
male
那么对应的bitmap则是这样存储的:
rowid的启示位置与结束位置rowid的启示位置与结束位置
malefemale
10
01
01
10
由 此可见,存储的空间大大的节省了,另外带来的收益就是扫描的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.01Execution 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.00Execution 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      |       |       |            |
—————————————————————————————请 着重注意红色部分。逻辑读大大降低!!
BTW:
我觉得我们除了传统的NESTLOOP,MERGE JOIN,HASH JOIN。这样看来又多了一种优化JOIN的方式。总结:
bitmap我们可能平时使用的不多,但是觉得它在特殊的应用场景,还 是有优势的。bitmap join index更是一种多表JOIN的新方式,很有意思。关于Oracle启动无法启动netmgr问题的解决Oracle10g在AIX上的安装准备工作《Oracle大型数据库系统在AIX/unix上的实战详解》 集中答疑 40相关资讯      oracle 
  • [INS-32052] Oracle基目录和Oracle  (07/22/2014 07:41:41)
  • Oracle 4个大对象(lobs)数据类型  (02/03/2013 12:33:05)
  • Oracle按时间段分组统计  (07/26/2012 10:36:48)
  • [Oracle] dbms_metadata.get_ddl的  (07/12/2013 07:37:30)
  • Liferay Portal 配置使用Oracle和  (07/31/2012 20:07:18)
  • Concurrent Request:Inactive   (07/20/2012 07:44:05)
本文评论 查看全部评论 (0)
表情: 姓名: 字数