位图连接索引

2.1 明确需求后使用位图索引
在创建位图连接索引时,它是两个表或多个表之间的索引值的连接,连接的结果存储在索引自身中;通过前期做连接并存储结果,当查询时通过扫描索引(避免两表或多表全表扫描)来获取数据,当然对于建立这样的索引,建立前需求必须明确; 请观察如下人员信息表(th04)和人员单位关系信息表(tbbsj)
人员信息表(th04)
行  ID         NAME   GENDER   IDCARD                 HOMEADDR   JOBNO  BIRTHDATE
1  789524  张三      男    429005198911261805   水晶洞1     1300440   05-AUG-79
2  564895  李四    男      429005198911296178   水晶洞2     1000209   14-AUG-79
...
....
人员单位关系信息表(tbbsj)
行  ID(单位ID)    IDCARD(人员身份证)      DNAME(单位名称)    JOINDATE(进入单位时间)     SRZW(所任职位)    GZZT(工作状态)    TSGX(特殊贡献)
1  785652       429005198911261805    太空建筑有限公司       2013-12-22 21:51:33           总经理助理             优                          暂无
2  5689556   429005198911296178     飞轮实业有限公司         2013-12-22 21:51:42          总经理小秘            良                           暂无
..
.....
已知人员信息数据量为:100万,人员单位关系信息数据量为:1106642,在建立普通索引的情况下获取人员IDCARD为:429005198911261805 的人员单位信息:
SQL> select t1.*,t2.* from th04 t1,tbbsj t2 
2 where t1.idcard=t2.idcard and t1.idcard='429005198911261805';
---------------------------------------------------------------------------------------------- 
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | 
---------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT | | 1 | 253 | 10959 (1)| 00:02:12 | | | 
|* 1 | HASH JOIN | | 1 | 253 | 10959 (1)| 00:02:12 | | | 
| 2 | PARTITION RANGE ALL| | 1 | 65 | 2661 (1)| 00:00:32 | 1 | 6 | 
|* 3 | TABLE ACCESS FULL | TH04 | 1 | 65 | 2661 (1)| 00:00:32 | 1 | 6 | 
|* 4 | TABLE ACCESS FULL | TBBSJ | 1 | 188 | 8297 (1)| 00:01:40 | | | 
---------------------------------------------------------------------------------------------- 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
1 - access("T1"."IDCARD"="T2"."IDCARD") 
3 - filter("T1"."IDCARD"='429005198911261805') 
4 - filter("T2"."IDCARD"='429005198911261805') 
Statistics 
---------------------------------------------------------- 
1 recursive calls 
0 db block gets 
40165 consistent gets 
40137 physical reads 
分析结果得知为获取IDCARD为: 429005198911261805的人员单位信息,两张大表都做了全表扫描;因为获得人员单位关系信息需求已经明确,为其创建位图连接索引:
SQL> create bitmap index ind_th04uniontbbsj on th04(t1.idcard) 
2 from th04 t1,tbbsj t2 
3 where t1.idcard=t2.idcard 
4 tablespace tbs03 
5* local ;
创建位图连接索引后再次查询:
SQL> select t1.*,t2.* from th04 t1,tbbsj t2 
2* where t1.idcard=t2.idcard and t1.idcard='429005198911261805';
----------------------------------------------------------------------------------------------------------------- 
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | 
----------------------------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT | | 1 | 253 | 5 (0)| 00:00:01 | | | 
| 1 | NESTED LOOPS | | 1 | 253 | 5 (0)| 00:00:01 | | | 
| 2 | TABLE ACCESS BY INDEX ROWID | TBBSJ | 1 | 188 | 3 (0)| 00:00:01 | | | 
|* 3 | INDEX UNIQUE SCAN | PK_IDCARD | 1 | | 2 (0)| 00:00:01 | | | 
| 4 | TABLE ACCESS BY GLOBAL INDEX ROWID| TH04 | 1 | 65 | 2 (0)| 00:00:01 | ROWID | ROWID | 
|* 5 | INDEX UNIQUE SCAN | CS_IDCARD | 1 | | 1 (0)| 00:00:01 | | | 
----------------------------------------------------------------------------------------------------------------- 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
3 - access("T2"."IDCARD"='429005198911261805') 
5 - access("T1"."IDCARD"='429005198911261805') 
Statistics 
---------------------------------------------------------- 
0 recursive calls 
0 db block gets 
3 consistent gets 
0 physical reads 
对于位图连接索引,它将主导表和关联表中的ROWID以及主导列的列值存储在索引中,查询数据时通过扫描索引提高查询效率:
人员信息表(TH04)ROWID     人员单位关系信息表(tbbsj)ROWID     IDCARD
AAASdEAAGAAB6w6AAY       AAASfXAAIAAAmCQAAE                    440621197102274116
AAASdEAAGAAB6z5AAf        AAASfXAAIAAAmCGAAX                     440621197311244423
AAASdEAAGAAB6zCAAl        AAASfXAAIAAAmCPAAW                    440621197405202427

2.2创建位图连接索引的注意事项:
2.2.1创建位图连接索引时WHERE 子句中的关联条件列必须是主键或唯一约束(不符合条件会报错ORA-25954: missing primary key or unique constraint on dimension);
2.2.2在指定索引列时,如果两表都具有相同列,必须使用表名.列名的方式指定或者别名.列名的方式指定(不符合条件会报错:ORA-00918: column ambiguously defined);
2.2.3 创建位图索引同样DML操作效率差,建立前请仔细分析表结构和数据DML操作率;
2.2.4 更新表数据时同样会有锁定主导表、关联表问题;

原文地址:https://www.cnblogs.com/zwl715/p/3856009.html