zoukankan      html  css  js  c++  java
  • 当执行计划中出现BITMAP CONVERSION TO ROWIDS关键字时,需要注意了。

    前言

    前些天优化了一些耗费buffers较多的SQL,但系统CPU降低的效果不明显,于是又拉了awr报告,查看了SQL ordered by Gets排名前列的SQL。

    分析

    SQL代码:

    select distinct pro5.value as CUSTOMERCODE,
                    to_date('19000101000000', 'yyyymmddhh24miss') as LAST_UPDATE_TIME,
                    pro2.value as NAME,
                    nvl(pro3.value, '$$400006000004') as GENDER,
                    decode(pro4.value,
                           '$$400003000001',
                           decode(length(trim(pro5.value)),
                                  18,
                                  substr(trim(pro5.value), 7, 8)),
                           null) as BIRTHDAY,
                    decode(pro4.value, '$$400003000001', pro5.value, null) as CERT_NO,
                    pro4.value as CERTIFICATE_TYPE,
                    pro5.value as CERTIFICATE_NO,
                    null as NATION,
                    null as EFFECTIVE_DATE,
                    null as EXPIRE_DATE
      from policy p
     inner join role r
        on p.topactualid = r.topactualid
       and r.kind = 'INSURANCECERTIFICATELIST'
     inner join property pro2
        on r.topactualid = pro2.topactualid
       and r.actualid = pro2.parentactualid
       and r.parentagreementid = pro2.parentagreementid
       and r.topagreementid = pro2.topagreementid
       and pro2.kind = 'CUSTOMERNAME'
     inner join property pro3
        on r.topactualid = pro3.topactualid
       and r.actualid = pro3.parentactualid
       and r.parentagreementid = pro3.parentagreementid
       and r.topagreementid = pro3.topagreementid
       and pro3.kind = 'PERSONSEX'
     inner join property pro4
        on r.topactualid = pro4.topactualid
       and r.actualid = pro4.parentactualid
       and r.parentagreementid = pro4.parentagreementid
       and r.topagreementid = pro4.topagreementid
       and pro4.kind = 'CERTIFICATETYPE'
     inner join property pro5
        on r.topactualid = pro5.topactualid
       and r.actualid = pro5.parentactualid
       and r.parentagreementid = pro5.parentagreementid
       and r.topagreementid = pro5.topagreementid
       and pro5.kind = 'CERTIFICATECODE' and pro5.value is not null
      left join endorsement e
        on p.endorsementid = e.endorsementid
     where p.productcode = '00070002'
       and p.currentflag = 'Y'
       and (p.uniquecode like '013100%' or p.uniquecode like '011000%')
       and ((p.policystatus = '$$900001103001') or
           (e.endorsementstatus = '$$900002106001' and
           e.ISSUEDATE > to_date('20160411', 'YYYYMMDD')))
    

    执行计划:

    Plan hash value: 3936231819
    
    ------------------------------------------------------------------------------------------------------------
    | Id  | Operation                             | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                      |                    |     1 |   336 |   124K  (1)| 00:24:55 |
    |   1 |  HASH UNIQUE                          |                    |     1 |   336 |   124K  (1)| 00:24:55 |
    |   2 |   NESTED LOOPS                        |                    |     1 |   336 |   124K  (1)| 00:24:55 |
    |   3 |    NESTED LOOPS                       |                    |     1 |   284 |   124K  (1)| 00:24:55 |
    |   4 |     NESTED LOOPS                      |                    |     1 |   232 |   124K  (1)| 00:24:55 |
    |   5 |      NESTED LOOPS                     |                    |    51 |  9180 |   124K  (1)| 00:24:50 |
    |   6 |       NESTED LOOPS                    |                    | 14950 |  1868K| 11388   (1)| 00:02:17 |
    |*  7 |        FILTER                         |                    |       |       |            |          |
    |   8 |         NESTED LOOPS OUTER            |                    |   701 | 58183 |  6559   (1)| 00:01:19 |
    |*  9 |          TABLE ACCESS FULL            | POLICY             |  2661 |   129K|  5834   (1)| 00:01:11 |
    |  10 |          TABLE ACCESS BY INDEX ROWID  | ENDORSEMENT        |     1 |    33 |     1   (0)| 00:00:01 |
    |* 11 |           INDEX UNIQUE SCAN           | ENDORSEMENT_PK     |     1 |       |     0   (0)| 00:00:01 |
    |* 12 |        TABLE ACCESS BY INDEX ROWID    | ROLE               |    21 |   945 |    25   (0)| 00:00:01 |
    |* 13 |         INDEX RANGE SCAN              | TC_ROLE66          |   453 |       |     4   (0)| 00:00:01 |
    |* 14 |       TABLE ACCESS BY INDEX ROWID     | PROPERTY           |     1 |    52 |   124K  (1)| 00:24:50 |
    |  15 |        BITMAP CONVERSION TO ROWIDS    |                    |       |       |            |          |
    |  16 |         BITMAP AND                    |                    |       |       |            |          |
    |  17 |          BITMAP CONVERSION FROM ROWIDS|                    |       |       |            |          |
    |* 18 |           INDEX RANGE SCAN            | TC_PROPERTY_PARENT |    12 |       |     3   (0)| 00:00:01 |
    |  19 |          BITMAP CONVERSION FROM ROWIDS|                    |       |       |            |          |
    |* 20 |           INDEX RANGE SCAN            | TC_PROPERTY24      |    12 |       |     3   (0)| 00:00:01 |
    |* 21 |      TABLE ACCESS BY INDEX ROWID      | PROPERTY           |     1 |    52 |    13   (0)| 00:00:01 |
    |* 22 |       INDEX RANGE SCAN                | TC_PROPERTY_PARENT |    12 |       |     3   (0)| 00:00:01 |
    |* 23 |     TABLE ACCESS BY INDEX ROWID       | PROPERTY           |     1 |    52 |     3   (0)| 00:00:01 |
    |* 24 |      INDEX RANGE SCAN                 | TC_PROPERTY_PARENT |    12 |       |     3   (0)| 00:00:01 |
    |* 25 |    TABLE ACCESS BY INDEX ROWID        | PROPERTY           |     1 |    52 |     3   (0)| 00:00:01 |
    |* 26 |     INDEX RANGE SCAN                  | TC_PROPERTY_PARENT |    12 |       |     3   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       7 - filter("P"."POLICYSTATUS"='$$900001103001' OR "E"."ENDORSEMENTSTATUS"='$$900002106001' AND 
                  "E"."ISSUEDATE">TIMESTAMP' 2016-04-11 00:00:00')
       9 - filter("P"."PRODUCTCODE"='00070002' AND ("P"."UNIQUECODE" LIKE '013100%' OR "P"."UNIQUECODE" 
                  LIKE '011000%') AND "P"."CURRENTFLAG"='Y')
      11 - access("P"."ENDORSEMENTID"="E"."ENDORSEMENTID"(+))
      12 - filter("R"."KIND"='INSURANCECERTIFICATELIST')
      13 - access("P"."TOPACTUALID"="R"."TOPACTUALID")
      14 - filter("PRO5"."VALUE" IS NOT NULL AND "PRO5"."KIND"='CERTIFICATECODE' AND 
                  "R"."PARENTAGREEMENTID"="PRO5"."PARENTAGREEMENTID" AND "R"."TOPAGREEMENTID"="PRO5"."TOPAGREEMENTID")
      18 - access("R"."ACTUALID"="PRO5"."PARENTACTUALID")
      20 - access("R"."TOPACTUALID"="PRO5"."TOPACTUALID")
      21 - filter("PRO2"."KIND"='CUSTOMERNAME' AND "R"."TOPACTUALID"="PRO2"."TOPACTUALID" AND 
                  "R"."PARENTAGREEMENTID"="PRO2"."PARENTAGREEMENTID" AND "R"."TOPAGREEMENTID"="PRO2"."TOPAGREEMENTID")
      22 - access("R"."ACTUALID"="PRO2"."PARENTACTUALID")
      23 - filter("PRO4"."KIND"='CERTIFICATETYPE' AND "R"."TOPACTUALID"="PRO4"."TOPACTUALID" AND 
                  "R"."PARENTAGREEMENTID"="PRO4"."PARENTAGREEMENTID" AND "R"."TOPAGREEMENTID"="PRO4"."TOPAGREEMENTID")
      24 - access("R"."ACTUALID"="PRO4"."PARENTACTUALID")
      25 - filter("PRO3"."KIND"='PERSONSEX' AND "R"."TOPACTUALID"="PRO3"."TOPACTUALID" AND 
                  "R"."PARENTAGREEMENTID"="PRO3"."PARENTAGREEMENTID" AND "R"."TOPAGREEMENTID"="PRO3"."TOPAGREEMENTID")
      26 - access("R"."ACTUALID"="PRO3"."PARENTACTUALID")
    

    分析:

    1)执行计划中 id = 15 关键字为BITMAP CONVERSION TO ROWIDS,此关键字在此之前都未遇见过,于是谷歌下,有了以下解释:

    1)出现这样的情况,是因为表中存在不适当的索引,这些索引列的唯一度不高,oracle就有可能选择两个这样的索引转为bitmap来执行

    2)根据这两个索引的值再确认共同有的ROWID,最后再通过ROWID回表提取符合条件的数据。

    2) 可以使用/*+ opt_param('_b_tree_bitmap_plans','false') */hint 在sql级消除bitmap

    3) 也可以删除选择率低的索引,建立复合索引进行改善

    4) 根据执行计划的谓词信息,我建立了如下索引:

    create index IDX_POLICY_01 on POLICY (PRODUCTCODE, CURRENTFLAG, UNIQUECODE);
    
    create index IDX_PROPERTY_TEST02 on PROPERTY (KIND, PARENTACTUALID, TOPACTUALID, PARENTAGREEMENTID, TOPAGREEMENTID, VALUE) nologging;

    5)建立索引后的执行计划:

    Plan hash value: 2001935116
    
    -----------------------------------------------------------------------------------------------------------
    | Id  | Operation                           | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                    |                     |     1 |   336 | 10938   (1)| 00:02:12 |
    |   1 |  HASH UNIQUE                        |                     |     1 |   336 | 10938   (1)| 00:02:12 |
    |   2 |   NESTED LOOPS                      |                     |     1 |   336 | 10937   (1)| 00:02:12 |
    |   3 |    NESTED LOOPS                     |                     |     1 |   284 | 10934   (1)| 00:02:12 |
    |   4 |     NESTED LOOPS                    |                     |     1 |   232 | 10931   (1)| 00:02:12 |
    |   5 |      NESTED LOOPS                   |                     |     1 |   180 | 10928   (1)| 00:02:12 |
    |   6 |       NESTED LOOPS                  |                     |   875 |   109K|  8301   (1)| 00:01:40 |
    |*  7 |        FILTER                       |                     |       |       |            |          |
    |   8 |         NESTED LOOPS OUTER          |                     |   300 | 24900 |  6500   (1)| 00:01:19 |
    |*  9 |          TABLE ACCESS FULL          | POLICY              |  2776 |   135K|  5751   (1)| 00:01:10 |
    |  10 |          TABLE ACCESS BY INDEX ROWID| ENDORSEMENT         |     1 |    33 |     1   (0)| 00:00:01 |
    |* 11 |           INDEX UNIQUE SCAN         | ENDORSEMENT_PK      |     1 |       |     0   (0)| 00:00:01 |
    |* 12 |        TABLE ACCESS BY INDEX ROWID  | ROLE                |     3 |   135 |     6   (0)| 00:00:01 |
    |* 13 |         INDEX RANGE SCAN            | TC_ROLE66           |    62 |       |     3   (0)| 00:00:01 |
    |* 14 |       INDEX RANGE SCAN              | IDX_PROPERTY_TEST02 |     1 |    52 |     3   (0)| 00:00:01 |
    |* 15 |      INDEX RANGE SCAN               | IDX_PROPERTY_TEST02 |     1 |    52 |     3   (0)| 00:00:01 |
    |* 16 |     INDEX RANGE SCAN                | IDX_PROPERTY_TEST02 |     1 |    52 |     3   (0)| 00:00:01 |
    |* 17 |    INDEX RANGE SCAN                 | IDX_PROPERTY_TEST02 |     1 |    52 |     3   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       7 - filter("P"."POLICYSTATUS"='$$900001103001' OR "E"."ENDORSEMENTSTATUS"='$$900002106001' AND 
                  "E"."ISSUEDATE">TIMESTAMP' 2016-04-11 00:00:00')
       9 - filter("P"."PRODUCTCODE"='00070002' AND ("P"."UNIQUECODE" LIKE '013100%' OR 
                  "P"."UNIQUECODE" LIKE '011000%') AND "P"."CURRENTFLAG"='Y')
      11 - access("P"."ENDORSEMENTID"="E"."ENDORSEMENTID"(+))
      12 - filter("R"."KIND"='INSURANCECERTIFICATELIST')
      13 - access("P"."TOPACTUALID"="R"."TOPACTUALID")
      14 - access("R"."ACTUALID"="PRO4"."PARENTACTUALID" AND "R"."TOPACTUALID"="PRO4"."TOPACTUALID" 
                  AND "R"."PARENTAGREEMENTID"="PRO4"."PARENTAGREEMENTID" AND 
                  "R"."TOPAGREEMENTID"="PRO4"."TOPAGREEMENTID" AND "PRO4"."KIND"='CERTIFICATETYPE')
      15 - access("R"."ACTUALID"="PRO3"."PARENTACTUALID" AND "R"."TOPACTUALID"="PRO3"."TOPACTUALID" 
                  AND "R"."PARENTAGREEMENTID"="PRO3"."PARENTAGREEMENTID" AND 
                  "R"."TOPAGREEMENTID"="PRO3"."TOPAGREEMENTID" AND "PRO3"."KIND"='PERSONSEX')
      16 - access("R"."ACTUALID"="PRO2"."PARENTACTUALID" AND "R"."TOPACTUALID"="PRO2"."TOPACTUALID" 
                  AND "R"."PARENTAGREEMENTID"="PRO2"."PARENTAGREEMENTID" AND 
                  "R"."TOPAGREEMENTID"="PRO2"."TOPAGREEMENTID" AND "PRO2"."KIND"='CUSTOMERNAME')
      17 - access("R"."ACTUALID"="PRO5"."PARENTACTUALID" AND "R"."TOPACTUALID"="PRO5"."TOPACTUALID" 
                  AND "R"."PARENTAGREEMENTID"="PRO5"."PARENTAGREEMENTID" AND 
                  "R"."TOPAGREEMENTID"="PRO5"."TOPAGREEMENTID" AND "PRO5"."KIND"='CERTIFICATECODE')
           filter("PRO5"."VALUE" IS NOT NULL)
    

    优化后

    建立索引后,sql从原来的450s降低到20s,buffers 消耗也显著降低。

  • 相关阅读:
    基于Python的人脸动漫转换
    let 与 var的区别
    【LeetCode】汇总
    【HDU】4632 Palindrome subsequence(回文子串的个数)
    【算法】均匀的生成圆内的随机点
    【LeetCode】725. Split Linked List in Parts
    【LeetCode】445. Add Two Numbers II
    【LeetCode】437. Path Sum III
    【LeetCode】222. Count Complete Tree Nodes
    【LeetCode】124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/wanbin/p/9514680.html
Copyright © 2011-2022 走看看