IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

ORACLE BITMAP INDEX

Alibaba DBA Team 2010-05-25 13:31:12 累计浏览 3,656 次
本机暂存
ORACLE的bitmap索引,我们用的很少。在我们的常理认识当中,我们用的最多就是类似性别,类型这种属性的字段,因为他们字段的种类很少。其实 BITMAP还是有很多优势以及一些特性的。

    首先在传统的INDEX里,我们在索引的存储上,一般是分为:header+index length+index value+rowid组成。如图:

2010-05-24_142946

    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,示意图如下:

dwhsg093

    bitmap join index

    bitmap join index,它的特点就是将多张表的JOIN结果,存储在一个索引里面,然后使用BITMAP的形式进行存储。图难画了,请见谅,改天有空的时候,再把图 补上。这个对于类似DW那样的多表join效率提高很明显。

    我今天做了一个测试,是用3张表join来做的,原来的SQL是这样的:

    zeus@CRMDB> select wt_customer.company_name,wt_customer.gmt_create

    2 from wt_customer,wt_CUSTOMER_EXT ,wt_CUSTOMER_BOOK

    3 where wt_customer.id=wt_CUSTOMER_EXT.Customer_Id

    4 and wt_CUSTOMER_BOOK.Customer_Id=wt_customer.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_CUSTOMER_BOOK_UK | 177 | 1062 | 1 (0)|

    | 4 | TABLE ACCESS BY INDEX ROWID| wt_CUSTOMER | 1 | 35 | 2 (0)|

    |* 5 | INDEX UNIQUE SCAN | wt_CUSTOMER_PK | 1 | | 1 (0)|

    |* 6 | INDEX RANGE SCAN | wt_CUSTOMER_EXT_CID_IND | 1 | 5 | 0 (0)|

    ―――――――――――――――――――――――――――――――――-

    一 个3表join,效率很差。如果我们创建BITMAP JOIN INDEX则可以避免这种情况的发生:

    zeus@CRMDB>CREATE BITMAP INDEX cust_wt_test

    2 ON wt_customer(wt_customer.company_name)

    3 FROM wt_customer,wt_CUSTOMER_EXT ,wt_CUSTOMER_BOOK

    4 WHERE wt_customer.id=wt_CUSTOMER_EXT.Customer_Id

    5 and wt_CUSTOMER_BOOK.Customer_Id=wt_customer.id

    6 tablespace zeus_ind ;

    Index created.

    Elapsed: 00:00:00.08

    再来看看SQL的执行计划:

    zeus@CRMDB>select wt_customer.company_name,wt_customer.gmt_create

    2 from wt_customer,wt_CUSTOMER_EXT ,wt_CUSTOMER_BOOK

    3 where wt_customer.id=wt_CUSTOMER_EXT.Customer_Id

    4 and wt_CUSTOMER_BOOK.Customer_Id=wt_customer.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_CUSTOMER | 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的新方式,很有意思。

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. Oracle MTS模式下 进程地址与会话信息 (累计阅读 14,409)
  2. 那些在11gR2中可能惹祸的新特性,一张列表帮助你摆脱升级11gR2带来的烦恼 (累计阅读 6,881)
  3. 性能测试工具sysbench简介 (累计阅读 6,027)
  4. 大于2GB的Listener.log和运行超过198天的主机上的Oracle实例 (累计阅读 5,863)
  5. 仅仅只备份是不够的 (累计阅读 5,825)
  6. Oracle Database 12c 新特性 - Native Top N 查询 (累计阅读 5,751)
  7. ORACLE最大可以存储多少数据量 (累计阅读 5,730)
  8. Oracle DBA的学习进阶成长树-从初出茅庐到高瞻远瞩 (累计阅读 5,603)
  9. 老托的Oracle 数据库Patch概念性小常识 (累计阅读 5,550)
  10. 查看oracle数据库用户下的所有空表 (累计阅读 5,505)