位图索引



郑重声明:由于本人水平有限,如有不对的地方请大神指正不甚感激(327568824@qq.com)

创建T6表,将dba_objects里的内容全部添加进去。

SQL> createtable t6 as select * from dba_objects;

Table created.

 

再多添加几次同样的内容

SQL> insert into t6 select * from t6;

71747 rowscreated.

SQL> /

143494 rowscreated.

SQL> /

286988 rowscreated.

T6添加位图索引

SQL> create bitmap index t6_bit_ind ont6(object_type);

Index created.

将同样的内容添复制到T7表中

SQL> createtable t7 as select * from t6;

Table created.

T7添加B树索引

SQL>createindex t7_ind on t7(object_type);

Index created.

 

我们可以看到B树索引比位图索引占用的空间要大。

SQL> select segment_name,bytes from user_segmentsWHERE segment_name='T6_BIT_IND' OR segment_name='T7_IND';

 

SEGMENT_NAME                                                       BYTES

---------------------------------------------------------------------------

T6_BIT_IND                                                         327680

T7_IND                                                            13631488

 

SQL> select count(*) from t6 whereobject_type='TABLE';

Execution Plan

----------------------------------------------------------

Plan hash value:1829406406

------------------------------------------------------------------------------------------

| Id | Operation                   | Name      | Rows | Bytes | Cost (%CPU)| Time    |

------------------------------------------------------------------------------------------

|  0 | SELECT STATEMENT            |           |     1 |   11 |    2   (0)| 00:00:01 |

|  1 | SORT AGGREGATE             |            |     1 |   11 |           |          |

|  2 |  BITMAP CONVERSION COUNT   |            | 21221 |   227K|    2  (0)| 00:00:01 |

|* 3 |   BITMAP INDEX SINGLE VALUE| T6_BIT_IND |      |      |            |         |

------------------------------------------------------------------------------------------

PredicateInformation (identified by operation id):

---------------------------------------------------

  3 - access("OBJECT_TYPE"='TABLE')

Note

-----

  - dynamic sampling used for this statement(level=2)

Statistics

----------------------------------------------------------

         0 recursive calls

         0 db block gets

         4 consistent gets

         0 physical reads

         0  redosize

       528 bytes sent via SQL*Net to client

       523 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 count(*) from t7 whereobject_type='TABLE';

Execution Plan

----------------------------------------------------------

Plan hash value:2455506375

----------------------------------------------------------------------------

| Id | Operation         | Name  | Rows | Bytes | Cost (%CPU)|Time     |

----------------------------------------------------------------------------

|  0 | SELECT STATEMENT  |       |    1 |     9 |   55  (0)| 00:00:01 |

|  1 | SORT AGGREGATE   |       |    1 |     9 |           |          |

|* 2 |  INDEX RANGE SCAN| T7_IND | 18954 |  166K|   55   (0)| 00:00:01 |

----------------------------------------------------------------------------

PredicateInformation (identified by operation id):

---------------------------------------------------

  2 - access("OBJECT_TYPE"='TABLE')

Statistics

----------------------------------------------------------

         0 recursive calls

         0 db block gets

        45 consistent gets

         0 physical reads

         0 redo size

       528 bytes sent via SQL*Net to client

       523 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 count(*) from t7 whereobject_type='TABLE' or object_type='INDEX';

Execution Plan

----------------------------------------------------------

Plan hash value:2567312643

-----------------------------------------------------------------------------

| Id | Operation          | Name   | Rows | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------

|  0 | SELECT STATEMENT   |       |    1 |     9 |  144  (0)| 00:00:02 |

|  1 | SORT AGGREGATE    |       |    1 |     9 |           |          |

|  2 |  INLIST ITERATOR  |       |      |       |           |          |

|* 3 |   INDEX RANGE SCAN| T7_IND | 52020 |  457K|  144   (0)| 00:00:02 |

-----------------------------------------------------------------------------

PredicateInformation (identified by operation id):

---------------------------------------------------

 3 - access("OBJECT_TYPE"='INDEX' OR"OBJECT_TYPE"='TABLE')

Statistics

----------------------------------------------------------

         0 recursive calls

         0 db block gets

       128 consistent gets

         0 physical reads

         0 redo size

       528 bytes sent via SQL*Net to client

       523 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 count(*) from t6 where object_type='TABLE' or object_type='INDEX';

Execution Plan

----------------------------------------------------------

Plan hash value:1642841110

-------------------------------------------------------------------------------------------

| Id | Operation                    | Name      | Rows | Bytes | Cost (%CPU)| Time    |

-------------------------------------------------------------------------------------------

|  0 | SELECT STATEMENT             |           |     1 |    9 |    5   (0)| 00:00:01 |

|  1 | SORT AGGREGATE              |           |    1 |     9 |            |         |

|  2 |  INLIST ITERATOR            |            |       |      |           |          |

|  3 |   BITMAP CONVERSION COUNT   |            | 53540 |   470K|    5  (0)| 00:00:01 |

|* 4 |    BITMAP INDEX SINGLE VALUE| T6_BIT_IND |      |      |            |         |

-------------------------------------------------------------------------------------------

PredicateInformation (identified by operation id):

---------------------------------------------------

  4 - access("OBJECT_TYPE"='INDEX'OR "OBJECT_TYPE"='TABLE')

Statistics

----------------------------------------------------------

         0 recursive calls

         0 db block gets

         8 consistent gets

         0 physical reads

         0 redo size

       528 bytes sent via SQL*Net to client

       523 bytes received via SQL*Net from client

         2 SQL*Net roundtrips to/from client

         0 sorts (memory)

         0 sorts (disk)

         1 rows processed

从上面4个例子,我们看出索引对重复数据上进行的and,or操作比B树索引更优。

原因是由于位图索引的每个键值中保存了该键值在那些记录中存在的信息,当Oracle要对不同键值进行ANDOR操作时,Oracle 只需通过对这些信息在各个行上的分布(实际上是对01的位运算)进行计算,即可得出最终的结果。

我认为,位图索引应该适用于下面两种情况:

    ● 适合OLAP数据库

    ● 重复率高的数据;
          ● 使用OR\AND这类逻辑操作


位图索引使用的范围非常有限,特别是对于一些OLTP 系统,位图索引是不适合的。 在OLTP 系统中,通常有大量的DML 操作,比如update、insert、delete。在这种情况下,位图索引会引起副作用。 NOT 逻辑运算,就可以很容易解决那些B树索引无法解决的问题,而且速度非常快。


      实际上,位图索引非常不适合有大量“写”操作的数据库,这和它的数据存储机制有关。位图索引的数据存储机制,它并不像B 树索引那样,每个键值中存放一个唯一的ROWID,对应表中的唯一记录。

在每一个位图索引键值中,可能都对应很多条表记录,这样就有一个问题:当一个会话修改了一条记录信息时,它将更新索引键值,而一个索引键值中又存储了很多行记录信息,结果就是,用户修改一行记录,会将对应的位图索引键值加锁。



会话1


SQL>select distinct sid from v$mystat;


      SID


----------


       60


 


SQL>create table t8(id int,name varchar(20));


 


Table created.


 


SQL>create bitmap index t8_bit_inx on t8(id);


 


Index created.


 


SQL>insert into t8 values(1,'a');


 


1 row created.


 


SQL>insert into t8 values(1,'b');


 


1 row created.


 


SQL>commit;


 


Commit complete.


 


SQL>select * from t8;


 


       ID NAME


---------- --------------------


        1 a


        1 b


 


SQL>update t8 set id=2 where name='1';


会话二:


SQL>select distinct sid from v$mystat;


 


      SID


----------


       66


 


SQL>    update t8 set id=2 where name='b';


我们可以看到操作被阻塞了,查看下v$lock


SQL>select sid,type,id1,id2,lmode,request,ctime,block from v$lock where sid in(60,66);


      SID TY        ID1        ID2     LMODE    REQUEST      CTIME     BLOCK


---------- -- ---------- -------------------- ---------- ---------- ----------


       60 AE        100          0          4          0       6337          2


       66 TX     524300       3696          0          4        280          0


       66 AE        100          0          4          0        322          2


       60 TO       5124          1          3          0       3918          2


       60 TM      87038          0         3          0        360          2


       66 TM      87038          0          3          0        280          2


       60 TX     524300       3696          6          0        351          1


       66 TX      65567       3549          6          0       280          2


 


8 rows selected



     v$lock 视图中可以看到,会话60持有一个会话66所需要的锁,所以会话66此时会被阻塞。


        OLTP 系统是一个在线交易频繁的系统,并发非常大,而并发DML操作正是位图索


引的硬伤,所以对于OLTP 系统,位图索引基本上是不适合的。


    上面的演示可以给位图索引所使用的范围下这样明确的界定:


    ● 适合海量数据的OLAP 或者数据仓库系统;


    ● 适合特定的SQL 操作;


    ● 不适合OLTP 系统。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值