位图索引浅析

位图索引存储方式如图所示,它的一个索引键值会指向多行数据。性别为X的行指向ROW1,ROW3,ROW4,ROW5诸如此类,位图索引对于相异基数(distinct cardinality)低的数据较为适合,但这个低是相对意义上的低,对这个数字很难进行量化。对于有几千万条记录来说2就是一个低数字,而在一个成千万上亿的记录表中甚至100000都能叫作为低。B Tree索引一般来讲应该是具有高度选择性的,与之相反,位图索引不该具有这么高的选择性,而是一般没有选择性。

实验观察原理:

EODA@PROD1> set echo on
EODA@PROD1> 
EODA@PROD1> create table t   --创建测试表
  2    ( gender not null,
  3  	 location not null,
  4  	 age_group not null,
  5  	 data
  6  	)
  7  	as
  8    select decode( round(dbms_random.value(1,2)),
  9    1, 'M',
 10    2, 'F' ) gender,
 11    ceil(dbms_random.value(1,50)) location,
 12    decode( round(dbms_random.value(1,5)),
 13    1,'18 and under',
 14    2,'19-25',
 15    3,'26-30',
 16    4,'31-40',
 17    5,'41 and over'),
 18    rpad( '*', 20, '*')
 19  from dual connect by level <=100000;

Table created.

EODA@PROD1> 
EODA@PROD1> create bitmap index gender_idx on t(gender);  --创建位图索引

Index created.

EODA@PROD1> create bitmap index location_idx on t(location);  --创建位图索引

Index created.

EODA@PROD1> create bitmap index age_group_idx on t(age_group);  --创建位图索引

Index created.

EODA@PROD1> 
EODA@PROD1> exec dbms_stats.gather_table_stats( user, 'T');

PL/SQL procedure successfully completed.

EODA@PROD1> 
EODA@PROD1> set lines 132
EODA@PROD1> set autotrace traceonly explain
EODA@PROD1> 
EODA@PROD1> select count(*)
  2  from t
  3  where gender = 'M'
  4  and location in ( 1, 10, 30 )
  5  and age_group = '41 and over';

Execution Plan
----------------------------------------------------------
Plan hash value: 320981916

-----------------------------------------------------------------------------------------------
| Id  | Operation		      | Name	      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	      | 	      |     1 |    13 |     9	(0)| 00:00:01 |
|   1 |  SORT AGGREGATE 	      | 	      |     1 |    13 | 	   |	      |
|   2 |   BITMAP CONVERSION COUNT     | 	      |   608 |  7904 |     9	(0)| 00:00:01 |
|   3 |    BITMAP AND		      | 	      |       |       | 	   |	      |
|   4 |     BITMAP OR		      | 	      |       |       | 	   |	      |
|*  5 |      BITMAP INDEX SINGLE VALUE| LOCATION_IDX  |       |       | 	   |	      |
|*  6 |      BITMAP INDEX SINGLE VALUE| LOCATION_IDX  |       |       | 	   |	      |
|*  7 |      BITMAP INDEX SINGLE VALUE| LOCATION_IDX  |       |       | 	   |	      |
|*  8 |     BITMAP INDEX SINGLE VALUE | AGE_GROUP_IDX |       |       | 	   |	      |
|*  9 |     BITMAP INDEX SINGLE VALUE | GENDER_IDX    |       |       | 	   |	      |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - access("LOCATION"=1)
   6 - access("LOCATION"=10)
   7 - access("LOCATION"=30)
   8 - access("AGE_GROUP"='41 and over')
   9 - access("GENDER"='M')

/* Oracle先分别读取了5 - access("LOCATION"=1),6 - access("LOCATION"=10),7 - access("LOCATION"=30)这三个值的位图
并对这三个位图按位进行逻辑或操作,然后与8 - access("AGE_GROUP"='41 and over'),9 - access("GENDER"='M')进行逻辑与操作
最后BITMAP CONVERSION COUNT统计个数。
 */
 
EODA@PROD1> 
EODA@PROD1> select *      --这个例子解读方法类似
  2  from t
  3  where (( gender = 'M' and location = 20 )
  4  	       or ( gender = 'F' and location = 22 ))
  5  and age_group = '18 and under';

Execution Plan
----------------------------------------------------------
Plan hash value: 1064409070

------------------------------------------------------------------------------------------------
| Id  | Operation		       | Name	       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	       |	       |   408 | 13872 |    68	 (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID   | T	       |   408 | 13872 |    68	 (0)| 00:00:01 |
|   2 |   BITMAP CONVERSION TO ROWIDS  |	       |       |       |	    |	       |
|   3 |    BITMAP AND		       |	       |       |       |	    |	       |
|*  4 |     BITMAP INDEX SINGLE VALUE  | AGE_GROUP_IDX |       |       |	    |	       |
|   5 |     BITMAP OR		       |	       |       |       |	    |	       |
|   6 |      BITMAP AND 	       |	       |       |       |	    |	       |
|*  7 |       BITMAP INDEX SINGLE VALUE| LOCATION_IDX  |       |       |	    |	       |
|*  8 |       BITMAP INDEX SINGLE VALUE| GENDER_IDX    |       |       |	    |	       |
|   9 |      BITMAP AND 	       |	       |       |       |	    |	       |
|* 10 |       BITMAP INDEX SINGLE VALUE| LOCATION_IDX  |       |       |	    |	       |
|* 11 |       BITMAP INDEX SINGLE VALUE| GENDER_IDX    |       |       |	    |	       |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("AGE_GROUP"='18 and under')
   7 - access("LOCATION"=22)
   8 - access("GENDER"='F')
  10 - access("LOCATION"=20)
  11 - access("GENDER"='M')
  
--位图适用于读密集型的环境,因为一个位图索引键条目会只想很多行的数据。  

--参考来源《Oracle编程艺术深入理解 数据库 体系结构(第三版)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值