• 当执行计划中出现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 消耗也显著降低。

  • 相关阅读:
    Session共享的解决方案
    用IIS配置反向代理
    authorization配置
    git之https或http方式设置记住用户名和密码的方法
    微信分享接口
    为你的Visual Studio单独设置代理服务器
    HTTP错误404.13
    MVC5的AuthorizeAttribute详解
    【MVC5】画面多按钮提交
    PetaPoco dynamic
  • 原文地址:https://www.cnblogs.com/wanbin/p/9514680.html
Copyright © 2020-2023  润新知