报表程序中的一段SQL运行很慢,代码如下:

优化前:

耗时:1337s

INSERT INTO PER_LTE_ZIB_PB_COMMISSION_07
SELECT P.TOPACTUALID,
Q.POLICYNO,
Q.ENDORSEMENTNO,
CASE
WHEN Q.ENDORSEMENTSTATUS = '$$900002107001' THEN
'1'
ELSE
NULL
END AS ENDORSE_CFLAG,
P.ROLEID,
P.OURFLAG,
P.HOSTFLAG,
P.AMOUNTOFPOLICYISSUINGFEES AS AMOUNTOFPOLICYISSUINGFEES,
P.UWCODE,
P.UWNAME,
'04' AS DATATYPE,
P.CURRENCYCODE,
T3.TOPACTUALID AS NEXTTOPACTUALID,
P.PAYEE,
P.PAYEENAME
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
LEFT JOIN (SELECT POLICYNO,
'0' AS ENDORSEMENTNO,
TOPACTUALID,
POLICYID,
NULL AS ENDORSEMENTSTATUS
FROM RPT_ST.POLICY
WHERE POLICYNO IS NOT NULL
AND ENDORSEMENTID IS NULL
AND POLICYSTATUS IS NOT NULL
UNION ALL
SELECT T1.POLICYNO,
T2.ENDORSEMENTNO,
T1.TOPACTUALID,
POLICYID,
T2.ENDORSEMENTSTATUS
FROM RPT_ST.POLICY T1
LEFT JOIN RPT_ST.ENDORSEMENT T2
ON T1.ENDORSEMENTID = T2.ENDORSEMENTID
WHERE T1.POLICYNO IS NOT NULL
AND T2.ENDORSEMENTNO IS NOT NULL
AND POLICYSTATUS IS NOT NULL
AND T2.ENDORSEMENTSTATUS <> '$$900002107001') Q
ON P.TOPACTUALID = Q.TOPACTUALID
LEFT JOIN (SELECT S.TOPACTUALID,
S.POLICYID,
S.POLICYSTATUS,
NULL AS PREPOLICYID
FROM RPT_ST.POLICY S
WHERE POLICYNO IS NOT NULL
AND ENDORSEMENTID IS NULL
AND POLICYSTATUS IS NOT NULL
UNION ALL
SELECT T1.TOPACTUALID,
T1.POLICYID,
T1.POLICYSTATUS,
T2.PREPOLICYID
FROM RPT_ST.POLICY T1
LEFT JOIN RPT_ST.ENDORSEMENT T2
ON T1.ENDORSEMENTID = T2.ENDORSEMENTID
WHERE T1.POLICYNO IS NOT NULL
AND T2.ENDORSEMENTNO IS NOT NULL
AND POLICYSTATUS IS NOT NULL
AND T2.ENDORSEMENTSTATUS <> '$$900002107001') T3
ON Q.POLICYID = T3.PREPOLICYID
AND T3.POLICYSTATUS IS NOT NULL
WHERE P.TOPACTUALID IN
(SELECT TOPACTUALID
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
WHERE P.OURFLAG || NVL(P.HOSTFLAG, 0) = '$$1000090000011')
AND P.ROLEID NOT IN
(SELECT ROLEID
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
WHERE P.OURFLAG || NVL(P.HOSTFLAG, 0) = '$$1000090000011')
AND Q.POLICYNO IS NOT NULL Plan hash value: 21661008 ---------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT|
---------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | | | 9145 (100)| | | |
|* 1 | FILTER | | | | | | | |
|* 2 | HASH JOIN SEMI | | 1 | 451 | 8782 (1)| 00:01:46 | | |
|* 3 | HASH JOIN | | 2 | 854 | 8418 (1)| 00:01:42 | | |
|* 4 | HASH JOIN OUTER | | 1 | 260 | 8056 (1)| 00:01:37 | | |
| 5 | VIEW | | 1 | 192 | 4028 (1)| 00:00:49 | | |
| 6 | UNION-ALL | | | | | | | |
| 7 | REMOTE | POLICY | 1 | 143 | 4028 (1)| 00:00:49 | ENOLC | R->S |
| 8 | REMOTE | | | | | | ENOLC | R->S |
| 9 | VIEW | | 1 | 68 | 4028 (1)| 00:00:49 | | |
| 10 | UNION-ALL | | | | | | | |
| 11 | REMOTE | POLICY | 1 | 130 | 4028 (1)| 00:00:49 | ENOLC | R->S |
| 12 | REMOTE | | | | | | ENOLC | R->S |
| 13 | TABLE ACCESS FULL| PER_LTE_ZIB_PB_COMMISSION_06 | 65448 | 10M| 361 (1)| 00:00:05 | | |
|* 14 | TABLE ACCESS FULL | PER_LTE_ZIB_PB_COMMISSION_06 | 654 | 15696 | 363 (2)| 00:00:05 | | |
|* 15 | TABLE ACCESS FULL | PER_LTE_ZIB_PB_COMMISSION_06 | 1 | 24 | 363 (2)| 00:00:05 | | |
--------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter( IS NULL)
2 - access("P"."TOPACTUALID"="TOPACTUALID")
3 - access("P"."TOPACTUALID"="Q"."TOPACTUALID")
4 - access("Q"."POLICYID"="T3"."PREPOLICYID")
14 - filter("P"."OURFLAG"||NVL("P"."HOSTFLAG",'0')='$$1000090000011')
15 - filter(("P"."OURFLAG"||NVL("P"."HOSTFLAG",'0')='$$1000090000011' AND LNNVL("ROLEID"<>:B1)))

分析

分析SQL代码,其中where 条件中有NOT IN(select roleid from per..)子查询。
去掉not in子查询,进行查询,能在3s内结果,由此该SQL性能瓶颈就出在NOT IN子查询上。
而NOT IN子查询,可以等价改写成left join,改写形式如下: P.ROLEID NOT IN
(SELECT ROLEID
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
WHERE P.OURFLAG || NVL(P.HOSTFLAG, 0) = '$$1000090000011') 改写成: LEFT JOIN (SELECT ROLEID
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
WHERE P.OURFLAG || NVL(P.HOSTFLAG, 0) = '$$1000090000011') D
ON D.ROLEID=P.ROLEID
where D.ROLEID IS NULL

整体改下SQL如下:

INSERT INTO PER_LTE_ZIB_PB_COMMISSION_07
SELECT P.TOPACTUALID,
Q.POLICYNO,
Q.ENDORSEMENTNO,
CASE
WHEN Q.ENDORSEMENTSTATUS = '$$900002107001' THEN
'1'
ELSE
NULL
END AS ENDORSE_CFLAG,
P.ROLEID,
P.OURFLAG,
P.HOSTFLAG,
P.AMOUNTOFPOLICYISSUINGFEES AS AMOUNTOFPOLICYISSUINGFEES,
P.UWCODE,
P.UWNAME,
'04' AS DATATYPE,
P.CURRENCYCODE,
T3.TOPACTUALID AS NEXTTOPACTUALID,
P.PAYEE,
P.PAYEENAME
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
LEFT JOIN (SELECT POLICYNO,
'0' AS ENDORSEMENTNO,
TOPACTUALID,
POLICYID,
NULL AS ENDORSEMENTSTATUS
FROM RPT_ST.POLICY
WHERE POLICYNO IS NOT NULL
AND ENDORSEMENTID IS NULL
AND POLICYSTATUS IS NOT NULL
UNION ALL
SELECT T1.POLICYNO,
T2.ENDORSEMENTNO,
T1.TOPACTUALID,
POLICYID,
T2.ENDORSEMENTSTATUS
FROM RPT_ST.POLICY T1
LEFT JOIN RPT_ST.ENDORSEMENT T2
ON T1.ENDORSEMENTID = T2.ENDORSEMENTID
WHERE T1.POLICYNO IS NOT NULL
AND T2.ENDORSEMENTNO IS NOT NULL
AND POLICYSTATUS IS NOT NULL
AND T2.ENDORSEMENTSTATUS <> '$$900002107001') Q
ON P.TOPACTUALID = Q.TOPACTUALID
LEFT JOIN (SELECT S.TOPACTUALID,
S.POLICYID,
S.POLICYSTATUS,
NULL AS PREPOLICYID
FROM RPT_ST.POLICY S
WHERE POLICYNO IS NOT NULL
AND ENDORSEMENTID IS NULL
AND POLICYSTATUS IS NOT NULL
UNION ALL
SELECT T1.TOPACTUALID,
T1.POLICYID,
T1.POLICYSTATUS,
T2.PREPOLICYID
FROM RPT_ST.POLICY T1
LEFT JOIN RPT_ST.ENDORSEMENT T2
ON T1.ENDORSEMENTID = T2.ENDORSEMENTID
WHERE T1.POLICYNO IS NOT NULL
AND T2.ENDORSEMENTNO IS NOT NULL
AND POLICYSTATUS IS NOT NULL
AND T2.ENDORSEMENTSTATUS <> '$$900002107001') T3
ON Q.POLICYID = T3.PREPOLICYID
AND T3.POLICYSTATUS IS NOT NULL
LEFT JOIN (SELECT ROLEID
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
WHERE P.OURFLAG || NVL(P.HOSTFLAG, 0) = '$$1000090000011') D
ON D.ROLEID=P.ROLEID
WHERE P.TOPACTUALID IN
(SELECT TOPACTUALID
FROM PER_LTE_ZIB_PB_COMMISSION_06 P
WHERE P.OURFLAG || NVL(P.HOSTFLAG, 0) = '$$1000090000011')
AND Q.POLICYNO IS NOT NULL
AND D.ROLEID IS NULL ----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT|
----------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 475 | 9145 (1)| 00:01:50 | | |
|* 1 | HASH JOIN SEMI | | 1 | 475 | 9145 (1)| 00:01:50 | | |
|* 2 | FILTER | | | | | | | |
|* 3 | HASH JOIN OUTER | | 1 | 451 | 8781 (1)| 00:01:46 | | |
|* 4 | HASH JOIN | | 2 | 854 | 8418 (1)| 00:01:42 | | |
|* 5 | HASH JOIN OUTER | | 1 | 260 | 8056 (1)| 00:01:37 | | |
| 6 | VIEW | | 1 | 192 | 4028 (1)| 00:00:49 | | |
| 7 | UNION-ALL | | | | | | | |
| 8 | REMOTE | POLICY | 1 | 143 | 4028 (1)| 00:00:49 | ENOLC | R->S |
| 9 | REMOTE | | | | | | ENOLC | R->S |
| 10 | VIEW | | 1 | 68 | 4028 (1)| 00:00:49 | | |
| 11 | UNION-ALL | | | | | | | |
| 12 | REMOTE | POLICY | 1 | 130 | 4028 (1)| 00:00:49 | ENOLC | R->S |
| 13 | REMOTE | | | | | | ENOLC | R->S |
| 14 | TABLE ACCESS FULL| PER_LTE_ZIB_PB_COMMISSION_06 | 65448 | 10M| 361 (1)| 00:00:05 | | |
|* 15 | TABLE ACCESS FULL | PER_LTE_ZIB_PB_COMMISSION_06 | 654 | 15696 | 363 (2)| 00:00:05 | | |
|* 16 | TABLE ACCESS FULL | PER_LTE_ZIB_PB_COMMISSION_06 | 654 | 15696 | 363 (2)| 00:00:05 | | |
---------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("P"."TOPACTUALID"="TOPACTUALID")
2 - filter("ROLEID" IS NULL)
3 - access("ROLEID"(+)="P"."ROLEID")
4 - access("P"."TOPACTUALID"="Q"."TOPACTUALID")
5 - access("Q"."POLICYID"="T3"."PREPOLICYID"(+))
15 - filter("P"."OURFLAG"(+)||NVL("P"."HOSTFLAG"(+),'0')='$$1000090000011')
16 - filter("P"."OURFLAG"||NVL("P"."HOSTFLAG",'0')='$$1000090000011') Remote SQL Information (identified by operation id):
---------------------------------------------------- 8 - SELECT "POLICYID","POLICYNO","POLICYSTATUS","TOPACTUALID","ENDORSEMENTID" FROM "CUAN_DOIC"."POLICY"
"POLICY" WHERE "ENDORSEMENTID" IS NULL AND "POLICYNO" IS NOT NULL AND "POLICYSTATUS" IS NOT NULL (accessing
'ENOLC' ) 9 - EXPLAIN PLAN INTO PLAN_TABLE@! FOR SELECT "A2"."POLICYNO","A1"."ENDORSEMENTNO","A2"."TOPACTUALID","A2".
"POLICYID","A1"."ENDORSEMENTSTATUS" FROM "CUAN_DOIC"."POLICY" "A2","CUAN_DOIC"."ENDORSEMENT" "A1" WHERE
"A2"."POLICYNO" IS NOT NULL AND "A1"."ENDORSEMENTNO" IS NOT NULL AND "A2"."POLICYSTATUS" IS NOT NULL AND
"A1"."ENDORSEMENTSTATUS"<>'$$900002107001' AND "A2"."ENDORSEMENTID"="A1"."ENDORSEMENTID" AND "A2"."POLICYNO"
IS NOT NULL (accessing 'ENOLC' ) 12 - SELECT "POLICYNO","POLICYSTATUS","TOPACTUALID","ENDORSEMENTID" FROM "CUAN_DOIC"."POLICY" "S" WHERE
"ENDORSEMENTID" IS NULL AND "POLICYNO" IS NOT NULL AND "POLICYSTATUS" IS NOT NULL (accessing 'ENOLC' ) 13 - EXPLAIN PLAN INTO PLAN_TABLE@! FOR SELECT "A2"."TOPACTUALID","A2"."POLICYID","A2"."POLICYSTATUS","A1"."
PREPOLICYID" FROM "CUAN_DOIC"."POLICY" "A2","CUAN_DOIC"."ENDORSEMENT" "A1" WHERE "A2"."POLICYNO" IS NOT NULL
AND "A1"."ENDORSEMENTNO" IS NOT NULL AND "A2"."POLICYSTATUS" IS NOT NULL AND
"A1"."ENDORSEMENTSTATUS"<>'$$900002107001' AND "A2"."ENDORSEMENTID"="A1"."ENDORSEMENTID" AND
"A2"."POLICYSTATUS" IS NOT NULL (accessing 'ENOLC' )

优化后

耗时:4s

SQL中带有NOT IN 子查询改写的更多相关文章

  1. SQL Server中INNER JOIN与子查询IN的性能测试

    这个月碰到几个人问我关于"SQL SERVER中INNER JOIN 与 IN两种写法的性能孰优孰劣?"这个问题.其实这个概括起来就是SQL Server中INNER JOIN与子 ...

  2. 你真的会玩SQL吗?无处不在的子查询

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  3. SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

    原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...

  4. SQL系列(九)—— 子查询(subQuery)

    1.子查询 前面的系列介绍的都是简单的查询场景,其中都只涉及到单张表的数据检索.但是在日常是实际应用中,数据模型之间的关系都非常的复杂,数据的需求一般都是来源于多个数据模型之间的组合而成,即对应多张表 ...

  5. Mysql常用sql语句(20)- 子查询重点知识

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 子查询语句可以嵌套在 sql 语句中任何表达式出现的位 ...

  6. paip.sql索引优化----join 代替子查询法

    paip.sql索引优化----join 代替子查询法 作者Attilax ,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.n ...

  7. 走向面试之数据库基础:二、SQL进阶之case、子查询、分页、join与视图

    一.CASE的两种用法 1.1 等值判断->相当于switch case (1)具体用法模板: CASE expression WHEN value1 THEN returnvalue1 WHE ...

  8. SQL主外键和子查询

    主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通过定义 PRIMARY KEY约束来创建主键.一个 ...

  9. SQL笔记-第八章,子查询

    一.SELECT列表中的标量子查询 查询每种书籍类型中的最早出版的书籍.在SQL 查询中,需要将一本书籍的出版年份与该类型的所有书籍的出版年份进行比较,并且仅仅在它们匹配时,才返回一个记录 SELEC ...

随机推荐

  1. 项目迁移腾讯云后,用户反馈,https证书不匹配。

    腾讯云大禹高防大禹BGP同一IP绑定多个证书,用户反馈无法匹配我们域名对应证书.但是浏览器是支持的.定位为客户端不支持sni在运维检查lb及高防证书关联无误,定位发现是用户端httpclient没有设 ...

  2. Ignatius and the Princess III HDU - 1028 || 整数拆分,母函数

    Ignatius and the Princess III HDU - 1028 整数划分问题 假的dp(复杂度不对) #include<cstdio> #include<cstri ...

  3. vue项目导出电子表格

    方法一: 一.安装依赖(前面基本一样) npm install file-saver --save npm install xlsx --save npm install script-loader ...

  4. HUST 1698 - 电影院 组合数学 + 分类思想

    http://acm.hust.edu.cn/problem/show/1698 题目就是要把一个数n分成4段,其中中间两段一定要是奇数. 问有多少种情况. 分类, 奇数 + 奇数 + 奇数 + 奇数 ...

  5. RabbitMQ七:交换机类型Exchange Types--Fanout 介绍

    前言 最新版本的RabbitMQ有四种交换机类型,分别是Direct exchange.Fanout exchange.Topic exchange.Headers exchange. 其中之前我们用 ...

  6. Linux之测试服务器和端口连通

    目录 wget工具 telnet工具 ssh工具 wget工具: 该工具是网络自动下载工具,如果linux或centos中不存在,需要先安装,支持http.https.ftp协议,wget名称的由来是 ...

  7. 关于flex布局对自己的影响

    对于本图来说用了一个效果就能达到这种情况,对于我来说,今天是有进步的,具体操作就是盒子模型确实,在什么地方起来的flex就运用到该地方去,刚 开始就一直有问题,思考了半天,原来是我的控制代码出现了点错 ...

  8. flex弹性布局操练2

    上一个是练习的1个内元素的,这次练习两个元素的. ul.box1 { list-style:none; background-color:black; display:flex; justify-co ...

  9. 一段js实现复制文本内容到剪切板

    <script type="text/javascript"> function copyUrl2() { var Url2=document.getElementBy ...

  10. NavigationView的使用

    代码已经分享至github:https://github.com/YanYoJun/NavigationDemo 转载请注明原文链接:http://www.cnblogs.com/yanyojun/p ...