首页 > 代码库 > 位图连接索引
位图连接索引
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 更新表数据时同样会有锁定主导表、关联表问题;