前言

前些天优化了一些耗费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 消耗也显著降低。

当执行计划中出现BITMAP CONVERSION TO ROWIDS关键字时,需要注意了。的更多相关文章

  1. SQL Server 2000中的并行处理和执行计划中的位图运算符

    SQL Server 2000中的并行处理和执行计划中的位图运算符 摘抄自:SQLServer 2000并行处理和位图简介 刘志斌 并行查询介绍Degree of Parallelism(并行度) 一 ...

  2. 浅析SQL SERVER执行计划中的各类怪相

    在查看执行计划或调优过程中,执行计划里面有些现象总会让人有些疑惑不解: 1:为什么同一条SQL语句有时候会走索引查找,有时候SQL脚本又不走索引查找,反而走全表扫描? 2:同一条SQL语句,查询条件的 ...

  3. [转载] EXPLAIN执行计划中要重点关注哪些要素

    原文: https://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=400738936&idx=1&sn=2910b4119b9 ...

  4. SQL Server 执行计划中的扫描方式举例说明

    SQL Server 执行计划中的扫描方式举例说明 原文地址:http://www.cnblogs.com/zihunqingxin/p/3201155.html 1.执行计划使用方式 选中需要执行的 ...

  5. 执行计划中常见index访问方式(转)

    近期有朋友对于单个表上的index各种情况比较模糊,这里对于单个表上,单个index出现的大多数情况进行了总结性测试,给出了测试结果,至于为什么出现这样的试验结果未做过多解释,给读者留下思考的空间.本 ...

  6. MySQL 执行计划中Extra(Using where,Using index,Using index condition,Using index,Using where)的浅析

      关于如何理解MySQL执行计划中Extra列的Using where.Using Index.Using index condition,Using index,Using where这四者的区别 ...

  7. 解读EXPLAIN执行计划中的key_len(转)

    原文:http://imysql.com/2015/10/20/mysql-faq-key-len-in-explain.shtml 导读 EXPLAIN中的key_len一列表示什么意思,该如何解读 ...

  8. EXPLAIN执行计划中要重点关注哪些要素(叶金荣)

    原文:http://mp.weixin.qq.com/s/CDKN_nPcIjzA_U5-xwAE5w 导读 EXPLAIN的结果中,有哪些关键信息值得注意呢? MySQL的EXPLAIN当然和ORA ...

  9. EXPLAIN执行计划中要重点关注哪些要素

    MySQL的EXPLAIN当然和ORACLE的没法比,不过我们从它输出的结果中,也可以得到很多有用的信息. 总的来说,我们只需要关注结果中的几列: 列名 备注 type 本次查询表联接类型,从这里可以 ...

随机推荐

  1. poj2676 Sudoku(搜索)

    题目链接:http://poj.org/problem?id=2676 题意:9*9的方格,0代表没数字,其他代表数字,请在格子中填入1~9的数字,使得在每行,每列和每个3*3的方块中,1~9的数字每 ...

  2. mariadb+centos7+主从复制

    MYSQL(mariadb) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的 ...

  3. flask框架路由系统

    flask框架的url系统: flask框架的路由系统: flask框架的路由系统使用实例化的route方法来指定: 如: @app.route('/') route函数装饰器可以把一个函数绑定到对应 ...

  4. macbook 快捷键 home ...

    home和end是fn+左右,ctrl+home和end是fn+cmd+左右

  5. 背包DP HDOJ 5410 CRB and His Birthday

    题目传送门 题意:有n个商店,有m金钱,一个商店买x件商品需要x*w[i]的金钱,得到a[i] * x + b[i]件商品(x > 0),问最多能买到多少件商品 01背包+完全背包:首先x == ...

  6. 贪心 Codeforces Round #173 (Div. 2) B. Painting Eggs

    题目传送门 /* 题意:给出一种方案使得abs (A - G) <= 500,否则输出-1 贪心:每次选取使他们相差最小的,然而并没有-1:) */ #include <cstdio> ...

  7. if判断的时候明明是null却不走null的函数体?

    String phoneStr = String.valueOf(parmMap.get(phone.trim())); if(StringUtils.isBlank(phoneStr) || &qu ...

  8. AJPFX:学习JAVA程序员两个必会的冒泡和选择排序

    * 数组排序(冒泡排序)* * 冒泡排序: 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处* * 选择排序 : 从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现 ...

  9. AJPFX关于Java NIO的概述总结

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Sel ...

  10. ES之各种运算符,for、while、do while 、switch case循环

    运算符优先级: 在所有的运算符中,括号的优先级最高,赋值符号的优先级最低. 小括号 > 计算运算符 > 比较运算符 > 逻辑运算符 > 赋值符号———————————————— ...