zt http://f.dataguru.cn/thread-226223-1-2.htmlhtml
位图索引是oracle中很是重要的一种索引形式。本文经过总结有关位图索引的资料,尝试回答以下几个问题:sql
1:什么是位图索引?数据库
2:位图索引适合什么场景,不适合什么场景?并发
3:位图索引的性能如何?oracle
什么是位图索引?app
位图索引,顾名思义,与“位”有关。你们都知道,计算机中的全部信息最终都是经过“位bit”来运算的, 二进制位运算在计算机中是很是高效的。每个二进制位均可以取值0或者1,而取值的确切含义是由具体的上下文环境决定的。在oracle位图索引中,每个二进制位表明了某一行中索引列的取值状况。例如,学生表中性别列的位图索引结构以下:dom
男:0101001101ide
女:1010110010oop
在上面的位图结构中,存储了10条学生记录的性别分布状况,以“男”性别为例,从左到右的第n个二进制位表明了第n条记录是否性别为男,若是二进制位为1,表明true即性别为男,0表明false即性别不为男。以此类推,从图中能够看出,第一条记录的性别为女,第二条记录的性别为男,...第九条记录的性别为女,第十条记录的性别为男。性能
你们都知道,在oracle中是根据rowid来定位记录的,所以,咱们须要引入start rowid和end rowid,经过start rowid ,end rowid 和二进制位的偏移,咱们就能够很是快速的计算出二进制位所表明的表记录rowid。位图索引的最终逻辑结构以下图:

位图索引适合什么场景,不适合什么场景?如今咱们已经了解了位图索引的逻辑结构,咱们称每一单元的<key ,startrowid,end rowid,bitmap>为一个位图片断。当咱们修改某一行数据的时候,咱们须要锁定该行列值所对应的位图片断,若是咱们进行的是更新操做,同时还会锁定更新后新值所在的位图片断。例如咱们将列值从01修改成03,就须要同时锁定01和03位图片断,此时若是有其余用户须要修改与01或者03关联的表记录上的索引字段,就会被阻塞,所以位图索引不适合并发环境,在并发环境下可能会形成大量事务的阻塞。
从位图索引的逻辑结构也能够看出,当索引列的distinct cardinality较大时,索引所占用的存储空间也会成比例扩大。下面咱们测试一下位图索引占用空间与distinct cardinality的关系:
数据库环境:oracle 11g
数据块大小:8k
[sql] view plaincopyprint?
- CREATE or replace FUNCTION ind_spc_test(rn NUMBER) RETURN NUMBER
- AS
- v_j NUMBER;
- v_dis NUMBER;
- v_bm_sp NUMBER;
- v_bt_sp NUMBER;
- BEGIN
- FOR i IN 1 .. 10LOOP
- EXECUTE immediate 'truncate table t_easy1';
- EXECUTE immediate 'truncate table t_easy2';
- SELECT floor(rn/(11-i)) INTO v_j FROM dual;
- FOR j IN 1 .. rn LOOP
- INSERT INTO t_easy1 VALUES (mod(j,v_j));
- INSERT INTO t_easy2 VALUES (mod(j,v_j));
- END LOOP;
- commit;
- select count(distinct id) into v_j from t_easy1;
- EXECUTE immediate 'analyze index i_easy1 COMPUTE STATISTICS';
- SELECT lEAF_BLOCKS INTO v_bt_sp FROM user_indexes where index_name='I_EASY1';
- EXECUTE immediate 'analyze index i_easy2 COMPUTE STATISTICS';
- SELECT LEAF_BLOCKS INTO v_bm_sp FROM user_indexes where index_name='I_EASY2';
- INSERT INTO bitmap_ind_space VALUES (v_j,v_bm_sp,v_bt_sp,rn );
- COMMIT;
- END LOOP;
- RETURN 0;
- END;
[sql] view plaincopyprint?
- SQL> select * from bitmap_ind_space order by 1;
-
- DISTINCT_VAL BITMAP_IND_BLKS BTREE_IND_BLKS ROW_NUM
- ------------ --------------- -------------- ----------
- 10000 139 300 100000
- 11111 79 335 100000
- 12500 89 285 100000
- 14285 103 220 100000
- 16666 120 257 100000
- 20000 146 310 100000
- 25000 183 293 100000
- 33333 246 262 100000
- 50000 371 296 100000
- 100000 408 200 100000
这里的测试比较简单,下面看看大师的实验结果:

从这里能够看出,随着distinct columns值的增长,位图索引占用空间逐步增大,但即使在最坏的状况下,位图索引占用的空间也仅仅是普通索引的2~3倍,在存储日益广泛的今天,这恐怕并非很大的问题。
位图索引的查询性能如何?下面咱们看一下位图索引的查询性能如何。
在不少资料中,均可以看到这样的论述:位图索引适合于 low distict cardinality的列。实际上,对于high distinct cardinality 的列,位图索引的查询性能也是很是不错的。下面咱们来验证这个结论。
首先咱们建立两张表:emp_normal和emp_random.
[sql] view plaincopyprint?
- SQL> create table emp_normal(empno number(10), ename varchar2(30), sal number(10));
-
- 表已建立。
-
- Begin
- For i in 1..1000000
- Loop
- Insert into emp_normal
- values(i, dbms_random.string('U',30), dbms_random.value(1000,7000));
- If mod(i, 10000) = 0 then
- Commit;
- End if;
- End loop;
- 10 End;
- 11 /
-
- PL/SQL 过程已成功完成。
-
- SQL> create table emp_random as select /* +append */ * from emp_normal order by dbms_random.random;
emp_random因为其记录是随机分布的,所以该表上索引的CLUSTERING_FACTOR要高一些。
咱们首先看一下emp_normal表等值查询状况下,索引的效率如何:
[sql] view plaincopyprint?
- SQL> create bitmap index bm_normal on emp_normal(empno);
-
- 索引已建立。
-
-
- SQL> analyze table emp_normal compute statistics for table for all indexes for all indexed columns;
-
- 表已分析。
-
- SQL> select index_name,clustering_factor from user_indexes;
-
- INDEX_NAME CLUSTERING_FACTOR
- ------------------------------ -----------------
- BM_NORMAL 1000000
-
- SQL> set autot traceonly
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 1000
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=1000
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 1526426521
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 3 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 | 34 | 3 (0)| 00:00:01 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX SINGLE VALUE | BM_NORMAL | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO"=1000)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 702 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
-
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 2398
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=2398
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 1526426521
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 3 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 | 34 | 3 (0)| 00:00:01 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX SINGLE VALUE | BM_NORMAL | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO"=2398)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 703 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
-
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 8545
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=8545
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 1526426521
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 3 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 | 34 | 3 (0)| 00:00:01 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX SINGLE VALUE | BM_NORMAL | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO"=8545)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 703 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
-
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 128444
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=128444
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 1526426521
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 3 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_NORMAL | 1 | 34 | 3 (0)| 00:00:01 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX SINGLE VALUE | BM_NORMAL | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO"=128444)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 704 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
-
- SQL> drop index bm_normal;
-
- 索引已删除。
-
- SQL> create index bt_normal on emp_normal(empno);
-
- 索引已建立。
-
- SQL> analyze table emp_normal compute statistics for table for all indexes for all indexed columns;
-
- 表已分析。
-
- SQL> select index_name,clustering_factor from user_indexes;
-
- INDEX_NAME CLUSTERING_FACTOR
- ------------------------------ -----------------
- BT_NORMAL 6210
- SYS_IL0000076897C00002$$
- PK_EMP 1
- PK_DEPT 1
-
- SQL> set autot traceonly
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 1000
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=1000
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 733975378
-
- ------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 4 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID| EMP_NORMAL | 1 | 34 | 4 (0)| 00:00:01 |
- |* 2 | INDEX RANGE SCAN | BT_NORMAL | 1 | | 3 (0)| 00:00:01 |
- ------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 2 - access("EMPNO"=1000)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 702 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
-
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 128444
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=128444
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 733975378
-
- ------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 4 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID| EMP_NORMAL | 1 | 34 | 4 (0)| 00:00:01 |
- |* 2 | INDEX RANGE SCAN | BT_NORMAL | 1 | | 3 (0)| 00:00:01 |
- ------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 2 - access("EMPNO"=128444)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 704 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
-
- SQL> select * from emp_normal where empno=&empno;
- 输入 empno 的值: 2398
- 原值 1: select * from emp_normal where empno=&empno
- 新值 1: select * from emp_normal where empno=2398
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 733975378
-
- ------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 34 | 4 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID| EMP_NORMAL | 1 | 34 | 4 (0)| 00:00:01 |
- |* 2 | INDEX RANGE SCAN | BT_NORMAL | 1 | | 3 (0)| 00:00:01 |
- ------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 2 - access("EMPNO"=2398)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 5 consistent gets
- 0 physical reads
- 0 redo size
- 703 bytes sent via SQL*Net to client
- 520 bytes received via SQL*Net from client
- 2 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1 rows processed
总结以下:
BITMAP |
EMPNO |
B-TREE |
Consistent Reads |
Physical Reads |
Consistent Reads |
Physical Reads |
5 |
0 |
1000 |
5 |
0 |
5 |
0 |
2398 |
5 |
0 |
5 |
0 |
8545 |
5 |
0 |
5 |
0 |
98008 |
5 |
0 |
5 |
0 |
85342 |
5 |
0 |
5 |
0 |
128444 |
5 |
0 |
5 |
0 |
858 |
5 |
0 |
对emp_random表进行实验,得出的结果与之相似,这里再也不獒述。从这里能够看出,在惟一列上的等值查询,位图索引与btree索引的效率至关。
下面,咱们在针对范围查询来进行测试。
[sql] view plaincopyprint?
- SQL> create bitmap index bm_random on emp_random(empno);
-
- 索引已建立。
-
- SQL> analyze table emp_random compute statistics for table for all indexes for all columns;
-
- 表已分析。
-
- SQL> select index_name,clustering_factor from user_indexes;
-
- INDEX_NAME CLUSTERING_FACTOR
- ------------------------------ -----------------
- BM_RANDOM 1000000
-
-
- SQL> set autot traceonly
- SQL> select * from emp_random where empno between &range1 and &range2;
- 输入 range1 的值: 1
- 输入 range2 的值: 2300
- 原值 1: select * from emp_random where empno between &range1 and &range2
- 新值 1: select * from emp_random where empno between 1 and 2300
-
- 已选择2300行。
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 811843605
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 2299 | 85063 | 418 (1)| 00:00:06 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_RANDOM | 2299 | 85063 | 418 (1)| 00:00:06 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX RANGE SCAN | BM_RANDOM | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO">=1 AND "EMPNO"<=2300)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 2463 consistent gets
- 0 physical reads
- 0 redo size
- 130225 bytes sent via SQL*Net to client
- 2203 bytes received via SQL*Net from client
- 155 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 2300 rows processed
-
- SQL> select * from emp_random where empno between &range1 and &range2;
- 输入 range1 的值: 8
- 输入 range2 的值: 1980
- 原值 1: select * from emp_random where empno between &range1 and &range2
- 新值 1: select * from emp_random where empno between 8 and 1980
-
- 已选择1973行。
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 811843605
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1972 | 72964 | 366 (0)| 00:00:05 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_RANDOM | 1972 | 72964 | 366 (0)| 00:00:05 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX RANGE SCAN | BM_RANDOM | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO">=8 AND "EMPNO"<=1980)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 2114 consistent gets
- 0 physical reads
- 0 redo size
- 111758 bytes sent via SQL*Net to client
- 1961 bytes received via SQL*Net from client
- 133 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1973 rows processed
-
- SQL> select * from emp_random where empno between &range1 and &range2;
- 输入 range1 的值: 28888
- 输入 range2 的值: 31850
- 原值 1: select * from emp_random where empno between &range1 and &range2
- 新值 1: select * from emp_random where empno between 28888 and 31850
-
- 已选择2963行。
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 811843605
-
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 2962 | 107K| 513 (0)| 00:00:07 |
- | 1 | TABLE ACCESS BY INDEX ROWID | EMP_RANDOM | 2962 | 107K| 513 (0)| 00:00:07 |
- | 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
- |* 3 | BITMAP INDEX RANGE SCAN | BM_RANDOM | | | | |
- -------------------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 3 - access("EMPNO">=28888 AND "EMPNO"<=31850)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 3172 consistent gets
- 0 physical reads
- 0 redo size
- 170625 bytes sent via SQL*Net to client
- 2687 bytes received via SQL*Net from client
- 199 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 2963 rows processed
-
- SQL> drop index bm_random;
-
- 索引已删除。
-
- SQL> create index bt_random on emp_random(empno);
-
- 索引已建立。
-
- SQL> analyze table emp_random compute statistics for table for all indexes for all columns;
-
- 表已分析。
-
- SQL> set autot off
- SQL> select index_name,clustering_factor from user_indexes;
-
- INDEX_NAME CLUSTERING_FACTOR
- ------------------------------ -----------------
- BT_RANDOM 999834
- SQL> set autot traceonly
- SQL> select * from emp_random where empno between &range1 and &range2;
- 输入 range1 的值: 1
- 输入 range2 的值: 2300
- 原值 1: select * from emp_random where empno between &range1 and &range2
- 新值 1: select * from emp_random where empno between 1 and 2300
-
- 已选择2300行。
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 731629521
-
- --------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- --------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 2299 | 85063 | 1735 (1)| 00:00:21 |
- |* 1 | TABLE ACCESS FULL| EMP_RANDOM | 2299 | 85063 | 1735 (1)| 00:00:21 |
- --------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 1 - filter("EMPNO"<=2300 AND "EMPNO">=1)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 6410 consistent gets
- 0 physical reads
- 0 redo size
- 121081 bytes sent via SQL*Net to client
- 2203 bytes received via SQL*Net from client
- 155 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 2300 rows processed
-
- SQL> select * from emp_random where empno between &range1 and &range2;
- 输入 range1 的值: 8
- 输入 range2 的值: 1980
- 原值 1: select * from emp_random where empno between &range1 and &range2
- 新值 1: select * from emp_random where empno between 8 and 1980
-
- 已选择1973行。
-
-
- 执行计划
- ----------------------------------------------------------
- Plan hash value: 731629521
-
- --------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- --------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1972 | 72964 | 1735 (1)| 00:00:21 |
- |* 1 | TABLE ACCESS FULL| EMP_RANDOM | 1972 | 72964 | 1735 (1)| 00:00:21 |
- --------------------------------------------------------------------------------
-
- Predicate Information (identified by operation id):
- ---------------------------------------------------
-
- 1 - filter("EMPNO"<=1980 AND "EMPNO">=8)
-
-
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 6388 consistent gets
- 0 physical reads
- 0 redo size
- 103922 bytes sent via SQL*Net to client
- 1961 bytes received via SQL*Net from client
- 133 SQL*Net roundtrips to/from client
- 0 sorts (memory)
- 0 sorts (disk)
- 1973 rows processed
概括以下,
BITMAP |
EMPNO (Range) |
B-TREE |
Consistent Reads |
Physical Reads |
Consistent Reads |
Physical Reads |
2463 |
0 |
1-2300 |
6410 |
0 |
2114 |
0 |
8-1980 |
6388 |
0 |
2572 |
0 |
1850-4250 |
6418 |
0 |
3172 |
0 |
28888-31850 |
6456 |
0 |
2762 |
0 |
82900-85478 |
6431 |
0 |
7254 |
0 |
984888-1000000 |
7254 |
0 |
从这里能够看出,位图索引要优于btree索引,这是由于btree索引的cluster factor 较大,从而优化器选择了全表扫描。即使在emp_normal 表下,即clustering factor较小时,位图索引btree索引至关的。所以在distinct cardinality 较大的状况下,范围扫描的效率位图索引也是不逊色与btree索引。
总结以下:
位图索引的查询性能常常是优于btree索引的,即使在distinct cardinality较大的状况下
位图索引不适合与dml频繁的环境
位图索引适用于DSS系统
位图索引能够进行逻辑运算,多个索引和同时在查询语句中发挥做用,这是一个很是重要的地方