zoukankan      html  css  js  c++  java
  • bitmap index

    bitmap index 适用于 dss(决策支持系统) 和Data warehouse,ORACLE 建议的是不要在繁重的OLTP中使用 bitmap index ,我
    个人建议:千万别在OLTP中使用bitmap index,否则你死定了。
    请看一下测试:
    SQL> create table test as select * from dba_objects;
    表已创建。
    SQL> update test set status='INVALID' where owner='SCOTT';
    已更新13行。
    SQL> commit;
    提交完成。
    SQL> exec dbms_stats.gather_table_stats('ROBINSON','TEST');
    PL/SQL 过程已成功完成。
    SQL> create bitmap index i_b_stats on test(status);
    索引已创建。
    SQL> select count(*) from test where status='INVALID';
      COUNT(*)
    ----------
            14
    执行计划
    ----------------------------------------------------------
    Plan hash value: 148891143
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |     1 |     7 |     1   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE             |           |     1 |     7 |            |          |
    |   2 |   BITMAP CONVERSION COUNT   |           | 24981 |   170K|     1   (0)| 00:00:01 |
    |*  3 |    BITMAP INDEX SINGLE VALUE| I_B_STATS |       |       |            |          |
    -----------------------------------------------------------------------------------------
    SQL> drop index i_b_stats ;
    索引已删除。
    SQL> exec dbms_stats.gather_table_stats('ROBINSON','TEST',method_opt=>'for columns size 10 status');
    PL/SQL 过程已成功完成。
    SQL> select count(*) from test where status='INVALID';
      COUNT(*)
    ----------
            14
    执行计划
    ----------------------------------------------------------
    Plan hash value: 680875269
    ------------------------------------------------------------------------------
    | Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |          |     1 |     7 |       (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE   |          |     1 |     7 |            |          |
    |*  2 |   INDEX RANGE SCAN| I_STATUS |     8 |    56 |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------
    SQL> select count(*) from test where status='VALID';
      COUNT(*)
    ----------
         49947
    执行计划
    ----------------------------------------------------------
    Plan hash value: 1531502959
    ----------------------------------------------------------------------------------
    | Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |          |     1 |     7 |    27   (8)| 00:00:01 |
    |   1 |  SORT AGGREGATE       |          |     1 |     7 |            |          |
    |*  2 |   INDEX FAST FULL SCAN| I_STATUS | 49948 |   341K|    27   (8)| 00:00:01 |
    ----------------------------------------------------------------------------------
    SQL> drop index i_status ;
    索引已删除。
    SQL> create bitmap index i_b_status on test(status);
    索引已创建。
    SQL> select count(*) from test where status='VALID';
      COUNT(*)
    ----------
         49947
    执行计划
    ----------------------------------------------------------
    Plan hash value: 1410402464
    --------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |            |     1 |     7 |     2   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE               |            |     1 |     7 |            |          |
    |   2 |   BITMAP CONVERSION COUNT     |            | 49948 |   341K|     2   (0)| 00:00:01 |
    |*  3 |    BITMAP INDEX FAST FULL SCAN| I_B_STATUS |       |       |            |          |
    --------------------------------------------------------------------------------------------
    可以看到bitmap(cost=2)的查询效率确实比B*tree(cost=27)效率高很多。
    现在我们来看看bitmap对于DML的影响。
    在三个session中同时执行
    insert into test select * from dba_objects where rownum<2;
    我这里就不贴了,我们看看ASH,看看v$session_wait,v$session.
    SQL> select sid,username,program,event from v$session where username is not null;
           SID USERNAME                       PROGRAM                                                          EVENT
    ---------- ------------------------------ ---------------------------------------------------------------- ----------------------------------------------------------------
           143 ROBINSON                       plsqldev.exe                                                     SQL*Net message from client
           144 ROBINSON                       plsqldev.exe                                                     enq: TX - row lock contention
           146 ROBINSON                       plsqldev.exe                                                     SQL*Net message from client
           159 ROBINSON                       sqlplus.exe                                                      enq: TX - row lock contention
    可以看到在sqlplus,plsqldev中分别发生了TX-row lock contention竞争,这个竞争就是由于刚才执行的
    insert into test select * from dba_objects where rownum<2;引起的。
    如果你不相信,我用ASH给你查找出来
    SQL> select session_id,event,count(*),sum(time_waited) from v$active_session_history where  session_state='WAITING'
      2  and time_waited>0 and sample_time>=(sysdate-&howlongago/(24*60))
      3  group by session_id,event order by 3 desc;

    SESSION_ID EVENT                                                              COUNT(*) SUM(TIME_WAITED)
    ---------- ---------------------------------------------------------------- ---------- ----------------
           144 enq: TX - row lock contention                                           146        435563478
           159 enq: TX - row lock contention                                           138        414017496
           167 db file parallel write                                                    7            64316
           165 control file parallel write                                               5            63539
           143 enq: TX - row lock contention                                             4         10362621
           166 log file parallel write                                                   2           133521
           165 control file sequential read                                              1            86807
           164 db file sequential read                                                   1            26782
           146 db file sequential read                                                   1              572
    9 rows selected
    SQL> select event, session_id,sql_id, p1,p2,p3 from v$active_session_history where sample_time>=(sysdate-&howlongago/(24*60)) and session_id=&sid;
    EVENT                                                            SESSION_ID SQL_ID                P1         P2         P3
    ---------------------------------------------------------------- ---------- ------------- ---------- ---------- ----------
    enq: TX - row lock contention                                           144 9n78yftyyayk1 1415053316     196632        978
    enq: TX - row lock contention                                           144 9n78yftyyayk1 1415053316     196632        978
    enq: TX - row lock contention                                           144 9n78yftyyayk1 1415053316     196632        978
    ............................................................................省略.....................................................................
    498 rows selected
    ASH 是 每隔1s收集一次统计信息,我这里查询除了498条,意思就是说等待了498秒,而且现在还在等待,我估计我不kill其中的一个session
    永远都,那么那两个会话将永远等待。
    SQL> select sql_text from v$sqlarea where sql_id='&sql_id';
    SQL_TEXT
    --------------------------------------------------------------------------------
    insert into test select * from dba_objects where rownum<2
    由此证明,引起TX-row lock contention就是 上面的那条insert语句.
    此时你除了kill其中一个session,别无办法。
    只有2,3个人并发的去操作某一个表,就发生了TX lock,如果并发再高点,估计整个表都无法用,在刚才那张表中,由于status只有valid和invalid两个值,当一条insert 执行的时候,如果status是valid的,由于要更新bitmap,需要lock status=valid的所有行,所以千万别在oltp中使用bitmap index 。

  • 相关阅读:
    P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 洛谷
    P2212 [USACO14MAR]浇地Watering the Fields 洛谷
    Python字体颜色设置
    Python小游戏 -- 猜数字
    数据结构 -- 链表&双向链表
    数据结构 -- 队列 & 循环队列 -- 数组实现
    数据结构 -- 栈的数组实现法
    洛谷P1036 选数
    如何让c语言使用结构体近似模拟c++中的类
    对c语言回调函数的理解
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330643.html
Copyright © 2011-2022 走看看