详解oracle bitmap位图索引

位图索引是oracle中非常重要的一种索引形式。本文通过总结有关位图索引的资料,尝试回答如下几个问题:

1:什么是位图索引?

2:位图索引适合什么场景,不适合什么场景?

3:位图索引的性能如何?


什么是位图索引?

位图索引,顾名思义,与“位”有关。大家都知道,计算机中的所有信息最终都是通过“位bit”来运算的, 二进制位运算在计算机中是非常高效的。每一个二进制位都可以取值0或者1,而取值的确切含义是由具体的上下文环境决定的。在oracle位图索引中,每一个二进制位代表了某一行中索引列的取值情况。例如,学生表中性别列的位图索引结构如下:

男:0101001101

女:1010110010

在上面的位图结构中,存储了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
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> 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> 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> 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
总结如下:
BITMAPEMPNOB-TREE
Consistent ReadsPhysical ReadsConsistent ReadsPhysical Reads
50100050
50239850
50854550
509800850
508534250
5012844450
5085850

对emp_random表进行实验,得出的结果与之类似,这里不再獒述。从这里可以看出,在唯一列上的等值查询,位图索引与btree索引的效率相当。

下面,我们在针对范围查询来进行测试。

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

归纳如下,

BITMAPEMPNO (Range)B-TREE
Consistent ReadsPhysical ReadsConsistent ReadsPhysical Reads
246301-230064100
211408-198063880
257201850-425064180
3172028888-3185064560
2762082900-8547864310
72540984888-100000072540

从这里可以看出,位图索引要优于btree索引,这是因为btree索引的cluster  factor 较大,从而优化器选择了全表扫描。即便在emp_normal 表下,即clustering factor较小时,位图索引btree索引相当的。因此在distinct cardinality 较大的情况下,范围扫描的效率位图索引也是不逊色与btree索引。

总结如下:

位图索引的查询性能经常是优于btree索引的,即便在distinct cardinality较大的情况下

位图索引不适合与dml频繁的环境

位图索引适用于DSS系统

位图索引可以进行逻辑运算,多个索引和同时在查询语句中发挥作用,这是一个非常重要的地方


 

  • 13
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
0; } ``` 程序运行时,会显示一个菜单,让用户选择不同的功能,例如: ``` 1位索引Bitmap Index)是一种特殊类型的索引,它使用位存储数据。对于列中的每个不同值,位索引都会创建一个位,其中每个位对应于表中的. 添加学生信息 2. 显示所有学生信息 3. 按总分排序 4. 按DataStructure成绩排序一行。如果值出现在行中,则相应的位设置为1,否则为0。通过使用位索 5. 按C成绩排序 6. 查找某一C成绩的记录 0. 退出程序 请选择操作引,可以快速地定位符合特定查询条件的行。 位索引通常用于低基数(即不同值数量较少)列上,例如性别列等。在这种情况下,位索引可以(输入数字): ``` 用户可以根据需要选择不同的功能,程序会根据用户的选择执行相应极大地减少磁盘 I/O 操作,提高查询性能。但是,如果列具有高基数(即的操作,例如: ``` 请输入学号:001 请输入姓名:张三 请输入DataStructure成绩:90 请输入不同值数量较多),则位索引的效率可能会降低。 在 Oracle 数据库中,可以使用 CREATEC成绩:80 添加成功 请选择操作(输入数字):2 学号 姓名 DataStructure C 总分 BITMAP INDEX 语句创建位索引,例如: ``` CREATE BITMAP INDEX idx_gender ON employees(gender); ``` 001 张三 90.0 80.0 170.0 请选择操作(输入数字):3 按总这将在 employees 表的 gender 列上创建一个位索引。在查询中使用位索引时,可以使用 BIT分排序结果: 学号 姓名 DataStructure C 总分 001 张三 90.0 80.0 MAP AND、BITMAP OR、BITMAP NOT 等操作符组合多个位索引,以获得更高效的查询性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值