ORACLE BITMAP INDEX
首先在传统的INDEX里,我们在索引的存储上,一般是分为:header+index length+index value+rowid组成。如图:
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是这样的:
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的新方式,很有意思。
建议继续学习:
- 由浅入深探究mysql索引结构原理、性能分析与优化 (阅读:14994)
- 浅谈MySQL索引背后的数据结构及算法 (阅读:9885)
- 由浅入深理解索引的实现(2) (阅读:6341)
- HBase二级索引与Join (阅读:5788)
- 如何建立合适的索引? (阅读:5365)
- InnODB和MyISAM索引统计集合 (阅读:5189)
- Innodb 表和索引结构 (阅读:4793)
- mysql查询中利用索引的机制 (阅读:4716)
- MySQL索引背后的数据结构及算法原理 (阅读:4418)
- mysql索引浅析 (阅读:4077)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:vogts 来源: Alibaba DBA Team
- 标签: BITMAP INDEX 索引
- 发布时间:2010-05-25 13:31:12
- [56] 如何拿下简短的域名
- [55] Oracle MTS模式下 进程地址与会话信
- [55] IOS安全–浅谈关于IOS加固的几种方法
- [53] Go Reflect 性能
- [52] android 开发入门
- [51] 图书馆的世界纪录
- [50] 读书笔记-壹百度:百度十年千倍的29条法则
- [47] 【社会化设计】自我(self)部分――欢迎区
- [37] 程序员技术练级攻略
- [31] 视觉调整-设计师 vs. 逻辑