从oracle9i起,oracle引进了一种新的索引类型:bitmap join index。和bitmap index建立在单个table上不同,bitmap join index是基于多表连接的,连接条件要求是等于的内连接(equi-inner join)。对于数据仓库而言,较普遍的是Fact table的外键列和相关的Dimension table的主键列的连接操作。 Bitmap join index能够消除查询中的连接操作,因为它实际上已经将连接的结果保存在索引当中了。而且,相对于在表的连接列上建普通bitmap index来说,bitmap join index需要更少的存储空间。 同样的基于连接的Metarialized view也可以用来消除连接操作。但bitmap join index比起物化视图来更有效率,因为通过bitmap join index可以直接将基于索引列的查询对应到事实表的rowid。 以oracle的sample schema SH中的sales和customers表做个例子 1.建立基于维度表中一个列的bitmap join index
create bitmap index sales_cust_gender_bjix
on sales(customers.cust_gender)
from sales,customers
where sales.cust_id=customers; 建立这样的bitmap join index后,下面的查询就可以从index中直接得到结果,而不再需要连接sales和custmoers两张表来获得结果了。相当于根据连接条件,将customers表中的cust_gender列保存到sales表中了。 select sum(sales.amount_sold)
from sales,customers
where sales.cust_id,customers.cust_id
and customers.cust_gender='M'; 通过将bitmap join index dump出来可以看到,实际上,索引是按照customers.cust_gender分成2个位图,每个位图映射到sales表的ROWID。所以根据customers.cust_gender来过滤连接结果时,从索引中可以直接得到目标数据在sales中的rowid,无须执行join操作了。 一个可能的执行计划如下:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3751 Card=1 Bytes=9)
1 0 SORT (AGGREGATE)
2 1 PARTITION RANGE (ALL)
3 2 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'SALES' (Cost=3751 Card=508136 Bytes=4573220)
4 3 BITMAP CONVERSION (TO ROWIDS)
5 4 BITMAP INDEX (SINGLE VALUE) OF 'IX_BITMAP' 2.建立基于一个维度表中多个列的bitmap join index
create bitmap index sales_cust_ms_bjix
on sales(customers.cust_gender,customers.cust_id)
from sales,customers
where sales.cust_id=customers.cust_id; 3.建立多个维度表到一个事实表的bitmap join indexcreate bitmap index sales_c_gender_p_cat_bjix
on sales(customers.cust_gender,products.prod_category)
from sales,customers,products
where sales.cust_id=customers.cust_id
and sales.prod_id=products.prod_id; 4.建立基于snowflake schme的bitmap join index
雪花模型的维度表被规范化为多个小表,也就是建index的时候需要额外连接其他几个表
create bitmap index sales_co_country_name_bjix
on sales(countries.country_name)
from sales,countries,customers
where sales.country_id=countries.country_id
and sales.cust_id=customers.cust_id;
Bitmap join index的一些限制条件
只支持CBO
只能是equi-inner连接,任何外连接都无法使用bitmap join index 多个连接条件只能是AND关系 只能在fact table上执行并行DML。如果在dimension table上执行并行DML,会导致索引变为unusable状态。 不同的事务中,只能并发更新一个表 在From字句中,任何一个表都不能出现两次 在索引组织表(IOT)和临时表上不能建立bitmap join index 索引只能基于dimenion table中的列 维度表用于连接的列只能是主键列或者是有唯一约束的列。
SQL> create bitmap index sales_cust_gender_bjix
2 on sales(customers.cust_gender)
3 from sales,customers
4 where sales.cust_id=customers.cust_id;
from sales,customers
*
ERROR at line 3:
ORA-25954: missing primary key or unique constraint on dimension 如果维度表的主键是组合主键,那么连接条件需要是全部主键列都参与 其他对于bitmap index的限制条件同样使用于bitmap join index,比如在分区表上只能是local,不能是global。
|