oracle bitmap and /and equal

来源:互联网 发布:ubuntu系统下载iso 编辑:程序博客网 时间:2024/06/07 02:29

bitmap and 还是 and equal,都是一种将两个索引选择出来的rowid合并的算法,可以理解索引扫描结果合并;

假设这里的条件使用这两个索引选择性也非常之高,那么这里使用bitmap是不会影响效率的。

我们的sql 5分钟没有跑完,查看计划,走了BITMAP CONVERSION TO ROWIDS。
 

  1. SQL> explain plan for 
  2.   2     select    a.username , 
  3.   3  a.membertype , 
  4.   4         a.providername , 
  5.   5         a.tradename , 
  6.   6         a.actor , 
  7.   7         a.telephone , 
  8.   8         a.mobilephone  , 
  9.   9         a.email , 
  10.  10         b.title , 
  11.  11         b.starttime , 
  12.  12         b.adminname  
  13.  13    from Seller000 a, Chatroom000 b 
  14.  14   where a.roomid = b.roomid 
  15.  15     and b.isshow = '1' 
  16.  16     and b.roomtype in ('0''1'
  17.  17     and a.signupdate > to_date('2012-08-01''yyyy-mm-dd hh24:mi:ss'
  18.  18     and a.signupdate < to_date('2012-09-01''yyyy-mm-dd hh24:mi:ss'
  19.  19   order by b.roomid; 
  20.  
  21. 已解释。 
  22.  
  23. SQL> select * from table(dbms_xplan.display); 
  24.  
  25. PLAN_TABLE_OUTPUT 
  26. -------------------------------------------------------------------------------------------------------------------- 
  27.  
  28. Plan hash value: 273647176 
  29.  
  30. ---------------------------------------------------------------------------------------------------------- 
  31. | Id  | Operation                          | Name                | Rows  | Bytes | Cost (%CPU)| Time  | 
  32. ---------------------------------------------------------------------------------------------------------- 
  33. |   0 | SELECT STATEMENT                   |                     |    11 |  1782 |    28  (11)| 00:00:01 | 
  34. |*  1 |  FILTER                            |                     |       |       |            |       | 
  35. |   2 |   TABLE ACCESS BY INDEX ROWID      | SELLER              |     1 |   112 |    28  (11)| 00:00:01 | 
  36. |   3 |    NESTED LOOPS                    |                     |    11 |  1782 |    28  (11)| 00:00:01 | 
  37. |*  4 |     TABLE ACCESS BY INDEX ROWID    | CHATROOM            | 10975 |   535K|     3   (0)| 00:00:01 | 
  38. |   5 |      INDEX FULL SCAN               | PK_CHATROOM         |     9 |       |     1   (0)| 00:00:01 | 
  39.  
  40. PLAN_TABLE_OUTPUT 
  41. -------------------------------------------------------------------------------------------------------------------- 
  42.  
  43. |   6 |     BITMAP CONVERSION TO ROWIDS    |                     |       |       |            |       | 
  44. |   7 |      BITMAP AND                    |                     |       |       |            |       | 
  45. |   8 |       BITMAP CONVERSION FROM ROWIDS|                     |       |       |            |       | 
  46. |*  9 |        INDEX RANGE SCAN            | IDX_SELLER_ROOMID   |   141 |       |     1   (0)| 00:00:01 | 
  47. |  10 |       BITMAP CONVERSION FROM ROWIDS|                     |       |       |            |       | 
  48. |  11 |        SORT ORDER BY               |                     |       |       |            |       | 
  49. |* 12 |         INDEX RANGE SCAN           | I_SELLER_SIGNUPDATE |   141 |       |     2   (0)| 00:00:01 | 
  50. ---------------------------------------------------------------------------------------------------------- 
  51.  
  52. Predicate Information (identified by operation id): 
  53. --------------------------------------------------- 
  54.  
  55. PLAN_TABLE_OUTPUT 
  56. -------------------------------------------------------------------------------------------------------------------- 
  57.  
  58.  
  59.    1 - filter(TO_DATE('2012-08-01','yyyy-mm-dd hh24:mi:ss')<TO_DATE('2012-09-01','yyyy-mm-dd 
  60.               hh24:mi:ss')) 
  61.    4 - filter("B"."ISSHOW"='1' AND ("B"."ROOMTYPE"='0' OR "B"."ROOMTYPE"='1')) 
  62.    9 - access("A"."ROOMID"="B"."ROOMID"
  63.   12 - access("A"."SIGNUPDATE">TO_DATE('2012-08-01','yyyy-mm-dd hh24:mi:ss'AND 
  64.               "A"."SIGNUPDATE"<TO_DATE('2012-09-01','yyyy-mm-dd hh24:mi:ss')) 
  65.  
  66. 已选择29行。 
  67.  
  68.  
  69. SQL> explain plan for 
  70.   2    select  /*+ opt_param('_b_tree_bitmap_plans''false') */   a.username , 
  71.   3  a.membertype , 
  72.   4         a.providername , 
  73.   5         a.tradename , 
  74.   6         a.actor , 
  75.   7         a.telephone , 
  76.   8         a.mobilephone  , 
  77.   9         a.email , 
  78.  10         b.title , 
  79.  11         b.starttime , 
  80.  12         b.adminname  
  81.  13    from Seller000 a, Chatroom000 b 
  82.  14   where a.roomid = b.roomid 
  83.  15     and b.isshow = '1' 
  84.  16     and b.roomtype in ('0''1'
  85.  17     and a.signupdate > to_date('2012-08-01''yyyy-mm-dd hh24:mi:ss'
  86.  18     and a.signupdate < to_date('2012-09-01''yyyy-mm-dd hh24:mi:ss'
  87.  19   order by b.roomid; 
  88.  
  89. 已解释。 
  90.  
  91. SQL> select * from table(dbms_xplan.display); 
  92.  
  93. PLAN_TABLE_OUTPUT 
  94. --------------------------------------------------------------------------------------------------------------- 
  95.  
  96. Plan hash value: 4238594111 
  97.  
  98. ---------------------------------------------------------------------------------------------------- 
  99. | Id  | Operation                      | Name              | Rows  | Bytes | Cost (%CPU)| Time     | 
  100. ---------------------------------------------------------------------------------------------------- 
  101. |   0 | SELECT STATEMENT               |                   |    11 |  1782 |   240   (0)| 00:00:03 | 
  102. |*  1 |  FILTER                        |                   |       |       |            |          | 
  103. |*  2 |   TABLE ACCESS BY INDEX ROWID  | SELLER            |     1 |   112 |    34   (0)| 00:00:01 | 
  104. |   3 |    NESTED LOOPS                |                   |    11 |  1782 |   240   (0)| 00:00:03 | 
  105. |*  4 |     TABLE ACCESS BY INDEX ROWID| CHATROOM          | 10975 |   535K|     3   (0)| 00:00:01 | 
  106. |   5 |      INDEX FULL SCAN           | PK_CHATROOM       |     9 |       |     1   (0)| 00:00:01 | 
  107.  
  108. PLAN_TABLE_OUTPUT 
  109. --------------------------------------------------------------------------------------------------------------- 
  110.  
  111. |*  6 |     INDEX RANGE SCAN           | IDX_SELLER_ROOMID |   141 |       |     1   (0)| 00:00:01 | 
  112. ---------------------------------------------------------------------------------------------------- 
  113.  
  114. Predicate Information (identified by operation id): 
  115. --------------------------------------------------- 
  116.  
  117.    1 - filter(TO_DATE('2012-08-01','yyyy-mm-dd 
  118.               hh24:mi:ss')<TO_DATE('2012-09-01','yyyy-mm-dd hh24:mi:ss')) 
  119.    2 - filter("A"."SIGNUPDATE">TO_DATE('2012-08-01','yyyy-mm-dd hh24:mi:ss'AND 
  120.               "A"."SIGNUPDATE"<TO_DATE('2012-09-01','yyyy-mm-dd hh24:mi:ss')) 
  121.    4 - filter("B"."ISSHOW"='1' AND ("B"."ROOMTYPE"='0' OR "B"."ROOMTYPE"='1')) 
  122.  
  123. PLAN_TABLE_OUTPUT 
  124. --------------------------------------------------------------------------------------------------------------- 
  125.  
  126.    6 - access("A"."ROOMID"="B"."ROOMID"
  127.  
  128. 已选择23行。 


出现这样的情况,是因为表中存在不适当的索引,这些索引列的唯一度不高,oracle就有可能选择两个这样的索引转为bitmap来执行,
根据这两个索引的值再确认共同有的ROWID,最后再通过ROWID回表提取符合条件的数据。
可以使用/*+ opt_param('_b_tree_bitmap_plans', 'false') */ hint在sql级消除bitmap。
最终解决方法,删除唯一度低的index,建立组合index。

删除索引IDX_SELLER_ROOMID,如果I_SELLER_SIGNUPDATE索引确认无用,也可以删除,IND_ROOMID_SIGNUPDATE是我们建立的组合索引,这样消除了BITMAP CONVERSION TO ROWIDS,30秒出结果。以下是新的执行计划:

  1. SQL> explain plan for 
  2.   2    select   a.username , 
  3.   3  a.membertype , 
  4.   4         a.providername , 
  5.   5         a.tradename , 
  6.   6         a.actor , 
  7.   7         a.telephone , 
  8.   8         a.mobilephone  , 
  9.   9         a.email , 
  10.  10         b.title , 
  11.  11         b.starttime , 
  12.  12         b.adminname  
  13.  13    from Seller000 a, Chatroom000 b 
  14.  14   where a.roomid = b.roomid 
  15.  15     and b.isshow = '1' 
  16.  16     and b.roomtype in ('0''1'
  17.  17     and a.signupdate > to_date('2012-08-01''yyyy-mm-dd hh24:mi:ss'
  18.  18     and a.signupdate < to_date('2012-09-01''yyyy-mm-dd hh24:mi:ss'
  19.  19   order by b.roomid; 
  20.  
  21. 已解释。 
  22.  
  23. SQL> select * from table(dbms_xplan.display); 
  24.  
  25. PLAN_TABLE_OUTPUT 
  26. ------------------------------------------------------------------------------------------------------------------------ 
  27.  
  28. Plan hash value: 2603971898 
  29.  
  30. -------------------------------------------------------------------------------------------------------- 
  31. | Id  | Operation                      | Name                  | Rows  | Bytes | Cost (%CPU)| Time     | 
  32. -------------------------------------------------------------------------------------------------------- 
  33. |   0 | SELECT STATEMENT               |                       |    11 |  1672 |     9   (0)| 00:00:01 | 
  34. |*  1 |  FILTER                        |                       |       |       |            |          | 
  35. |   2 |   TABLE ACCESS BY INDEX ROWID  | SELLER                |     1 |   102 |     1   (0)| 00:00:01 | 
  36. |   3 |    NESTED LOOPS                |                       |    11 |  1672 |     9   (0)| 00:00:01 | 
  37. |*  4 |     TABLE ACCESS BY INDEX ROWID| CHATROOM              |  9978 |   487K|     3   (0)| 00:00:01 | 
  38. |   5 |      INDEX FULL SCAN           | PK_CHATROOM           |     9 |       |     1   (0)| 00:00:01 | 
  39.  
  40. PLAN_TABLE_OUTPUT 
  41. ------------------------------------------------------------------------------------------------------------------------ 
  42.  
  43. |*  6 |     INDEX RANGE SCAN           | IND_ROOMID_SIGNUPDATE |     1 |       |     1   (0)| 00:00:01 | 
  44. -------------------------------------------------------------------------------------------------------- 
  45.  
  46. Predicate Information (identified by operation id): 
  47. --------------------------------------------------- 
  48.  
  49.    1 - filter(TO_DATE('2012-08-01','yyyy-mm-dd hh24:mi:ss')<TO_DATE('2012-09-01','yyyy-mm-dd 
  50.               hh24:mi:ss')) 
  51.    4 - filter("B"."ISSHOW"='1' AND ("B"."ROOMTYPE"='0' OR "B"."ROOMTYPE"='1')) 
  52.    6 - access("A"."ROOMID"="B"."ROOMID" AND "A"."SIGNUPDATE">TO_DATE('2012-08-01','yyyy-mm-dd 
  53.               hh24:mi:ss') AND "A"."SIGNUPDATE"<TO_DATE('2012-09-01','yyyy-mm-dd hh24:mi:ss')) 
  54.  
  55. 已选择22行。 

 

原创粉丝点击