背景:

接到开发通知,应用页面打不开,让我协助。。。

(开发跟我说,表GV_BOOKS一直有锁,锁了有1个多小时了,问我能不能把锁释放掉,我回答他们说,这肯定是sql性能问题,表上有锁是正常现象,不是锁导致的sql执行不出来)。

利用工具,追踪到以下sql。

--sql代码
DELETE GV_BOOKS
WHERE ACCOUNTID IN
(SELECT ACCOUNTID
FROM GV_BOOKS
MINUS
SELECT A.ACCOUNTID
FROM GV_ACCOUNTS A, VW_BP_ACCOUNT_SYN B
WHERE A.DBLINK = B.DB_LINK
AND A.ACCOUNTNO = B.ACNTNO
MINUS
SELECT A.ACCOUNTID
FROM GV_ACCOUNTS A, VW_CNTACNT_GVIEW B
WHERE A.DBLINK = B.DB_LINK
AND A.ACCOUNTNO = B.NO); --执行计划
Plan hash value: 1376647110 -------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 110M| 2734M| 1129 (19)| 00:00:14 |
| 1 | DELETE | GV_BOOKS | | | | |
|* 2 | FILTER | | | | | |
| 3 | TABLE ACCESS FULL | GV_BOOKS | 86600 | 2198K| 104 (2)| 00:00:02 |
| 4 | MINUS | | | | | |
| 5 | MINUS | | | | | |
| 6 | SORT UNIQUE NOSORT | | 1274 | 5096 | 7 (15)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | IX_GV_BOOKS | 1274 | 5096 | 6 (0)| 00:00:01 |
| 8 | SORT UNIQUE NOSORT | | 1 | 39 | 5 (20)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 39 | 4 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID | GV_ACCOUNTS | 1 | 23 | 1 (0)| 00:00:01 |
|* 11 | INDEX UNIQUE SCAN | PK_GV_ACCOUNTS | 1 | | 0 (0)| 00:00:01 |
|* 12 | TABLE ACCESS FULL | BP_ACCOUNT | 1 | 16 | 3 (0)| 00:00:01 |
| 13 | NESTED LOOPS OUTER | | 1 | 96 | 2 (0)| 00:00:01 |
| 14 | NESTED LOOPS OUTER | | 1 | 83 | 2 (0)| 00:00:01 |
| 15 | NESTED LOOPS OUTER | | 1 | 70 | 2 (0)| 00:00:01 |
| 16 | NESTED LOOPS OUTER | | 1 | 57 | 2 (0)| 00:00:01 |
| 17 | NESTED LOOPS | | 1 | 44 | 2 (0)| 00:00:01 |
|* 18 | TABLE ACCESS BY INDEX ROWID| GV_ACCOUNTS | 1 | 23 | 1 (0)| 00:00:01 |
|* 19 | INDEX UNIQUE SCAN | PK_GV_ACCOUNTS | 1 | | 0 (0)| 00:00:01 |
| 20 | TABLE ACCESS BY INDEX ROWID| CB_ACCOUNT | 81 | 1701 | 1 (0)| 00:00:01 |
|* 21 | INDEX UNIQUE SCAN | IX_CB_ACC_NO | 1 | | 0 (0)| 00:00:01 |
|* 22 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 81 | 1053 | 0 (0)| 00:00:01 |
|* 23 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 81 | 1053 | 0 (0)| 00:00:01 |
|* 24 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 81 | 1053 | 0 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 81 | 1053 | 0 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter( EXISTS ( (SELECT "ACCOUNTID" FROM "GV_BOOKS" "GV_BOOKS" WHERE
"ACCOUNTID"=:B1)MINUS (SELECT "A"."ACCOUNTID" FROM NSTCSA."BP_ACCOUNT"
"BP_ACCOUNT","GV_ACCOUNTS" "A" WHERE "A"."ACCOUNTID"=:B2 AND "A"."DBLINK"='90' AND
"A"."ACCOUNTNO"="ACNTNO")MINUS (SELECT "A"."ACCOUNTID" FROM NSTCSA."CB_ACCOUNT_EXT"
"E",NSTCSA."CB_ACCOUNT_EXT" "D",NSTCSA."CB_ACCOUNT_EXT" "C",NSTCSA."CB_ACCOUNT_EXT"
"B",NSTCSA."CB_ACCOUNT" "A","GV_ACCOUNTS" "A" WHERE "A"."ACCOUNTID"=:B3 AND "A"."DBLINK"='90'
AND "A"."ACCOUNTNO"="A"."ACCOUNT_NO" AND "B"."EXT_KEY"(+)='CALCINTR' AND
"A"."ACCOUNT_ID"="B"."ACCOUNT_ID"(+) AND "C"."EXT_KEY"(+)='DAYMODE' AND
"A"."ACCOUNT_ID"="C"."ACCOUNT_ID"(+) AND "D"."EXT_KEY"(+)='FEEMODE1' AND
"A"."ACCOUNT_ID"="D"."ACCOUNT_ID"(+) AND "E"."EXT_KEY"(+)='FEEMODE2' AND
"A"."ACCOUNT_ID"="E"."ACCOUNT_ID"(+))))
7 - access("ACCOUNTID"=:B1)
10 - filter("A"."DBLINK"='90')
11 - access("A"."ACCOUNTID"=:B1)
12 - filter("A"."ACCOUNTNO"="ACNTNO")
18 - filter("A"."DBLINK"='90')
19 - access("A"."ACCOUNTID"=:B1)
21 - access("A"."ACCOUNTNO"="A"."ACCOUNT_NO")
22 - access("A"."ACCOUNT_ID"="E"."ACCOUNT_ID"(+) AND "E"."EXT_KEY"(+)='FEEMODE2')
23 - access("A"."ACCOUNT_ID"="D"."ACCOUNT_ID"(+) AND "D"."EXT_KEY"(+)='FEEMODE1')
24 - access("A"."ACCOUNT_ID"="C"."ACCOUNT_ID"(+) AND "C"."EXT_KEY"(+)='DAYMODE')
25 - access("A"."ACCOUNT_ID"="B"."ACCOUNT_ID"(+) AND "B"."EXT_KEY"(+)='CALCINTR')

分析

表信息

GV_BOOKS :86668行数据

子查询 :1行数据

由以上信息可以想到,让子查询方向驱动主表GV_BOOKS

改写后代码:

执行时间 :1s内

DELETE /*+ use_nl(tp@a,GV_BOOKS) */ GV_BOOKS
WHERE ACCOUNTID IN (select /*+ qb_name(a)*/ ACCOUNTID from
(SELECT ACCOUNTID
FROM GV_BOOKS
MINUS
SELECT A.ACCOUNTID
FROM GV_ACCOUNTS A, VW_BP_ACCOUNT_SYN B
WHERE A.DBLINK = B.DB_LINK
AND A.ACCOUNTNO = B.ACNTNO
MINUS
SELECT A.ACCOUNTID
FROM GV_ACCOUNTS A, VW_CNTACNT_GVIEW B
WHERE A.DBLINK = B.DB_LINK
AND A.ACCOUNTNO = B.NO) tp); Plan hash value: 9035204 ----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 1 | 104 | 13 (31)| 00:00:01 |
| 1 | DELETE | GV_BOOKS | | | | |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 1 | 104 | 13 (31)| 00:00:01 |
| 4 | VIEW | | 1 | 13 | 13 (31)| 00:00:01 |
| 5 | MINUS | | | | | |
| 6 | MINUS | | | | | |
| 7 | SORT UNIQUE | | 1 | 13 | | |
| 8 | TABLE ACCESS FULL | GV_BOOKS | 1 | 13 | 2 (0)| 00:00:01 |
| 9 | SORT UNIQUE | | 1 | 66 | | |
|* 10 | HASH JOIN | | 1 | 66 | 6 (17)| 00:00:01 |
|* 11 | TABLE ACCESS FULL | GV_ACCOUNTS | 1 | 49 | 2 (0)| 00:00:01 |
| 12 | TABLE ACCESS FULL | BP_ACCOUNT | 33 | 561 | 3 (0)| 00:00:01 |
| 13 | SORT UNIQUE | | 1 | 117 | | |
| 14 | NESTED LOOPS OUTER | | 1 | 117 | 2 (0)| 00:00:01 |
| 15 | NESTED LOOPS OUTER | | 1 | 105 | 2 (0)| 00:00:01 |
| 16 | NESTED LOOPS OUTER | | 1 | 93 | 2 (0)| 00:00:01 |
| 17 | NESTED LOOPS OUTER | | 1 | 81 | 2 (0)| 00:00:01 |
| 18 | NESTED LOOPS | | 1 | 69 | 2 (0)| 00:00:01 |
|* 19 | TABLE ACCESS FULL | GV_ACCOUNTS | 1 | 49 | 2 (0)| 00:00:01 |
| 20 | TABLE ACCESS BY INDEX ROWID| CB_ACCOUNT | 1 | 20 | 0 (0)| 00:00:01 |
|* 21 | INDEX UNIQUE SCAN | IX_CB_ACC_NO | 1 | | 0 (0)| 00:00:01 |
|* 22 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 12 | 0 (0)| 00:00:01 |
|* 23 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 12 | 0 (0)| 00:00:01 |
|* 24 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 12 | 0 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 12 | 0 (0)| 00:00:01 |
|* 26 | INDEX RANGE SCAN | IX_GV_BOOKS | 1 | | 0 (0)| 00:00:01 |
| 27 | TABLE ACCESS BY INDEX ROWID | GV_BOOKS | 1 | 91 | 0 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 10 - access("A"."ACCOUNTNO"="ACNTNO")
11 - filter("A"."DBLINK"='90')
19 - filter("A"."DBLINK"='90')
21 - access("A"."ACCOUNTNO"="A"."ACCOUNT_NO")
22 - access("A"."ACCOUNT_ID"="D"."ACCOUNT_ID"(+) AND "D"."EXT_KEY"(+)='FEEMODE1')
23 - access("A"."ACCOUNT_ID"="C"."ACCOUNT_ID"(+) AND "C"."EXT_KEY"(+)='DAYMODE')
24 - access("A"."ACCOUNT_ID"="B"."ACCOUNT_ID"(+) AND "B"."EXT_KEY"(+)='CALCINTR')
25 - access("A"."ACCOUNT_ID"="E"."ACCOUNT_ID"(+) AND "E"."EXT_KEY"(+)='FEEMODE2')
26 - access("ACCOUNTID"="ACCOUNTID")

优化方法二:

根据原sql执行计划,看出sql是走的filter,也就是子查询并未展开。

所以添加hint(unnest)让优化器对子查询展开。

执行时间:1s内

--执行计划
Plan hash value: 4288598425 -------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 110M| 4101M| | 1513 (53)| 00:00:19 |
| 1 | DELETE | GV_BOOKS | | | | | |
|* 2 | HASH JOIN | | 110M| 4101M| 2120K| 1513 (53)| 00:00:19 |
| 3 | VIEW | VW_NSO_1 | 86600 | 1099K| | 372 (3)| 00:00:05 |
| 4 | MINUS | | | | | | |
| 5 | MINUS | | | | | | |
| 6 | SORT UNIQUE | | 86600 | 338K| 1032K| | |
| 7 | TABLE ACCESS FULL | GV_BOOKS | 86600 | 338K| | 103 (1)| 00:00:02 |
| 8 | SORT UNIQUE | | 87 | 3393 | | | |
|* 9 | HASH JOIN | | 87 | 3393 | | 7 (15)| 00:00:01 |
|* 10 | TABLE ACCESS FULL | GV_ACCOUNTS | 87 | 2001 | | 3 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | BP_ACCOUNT | 87 | 1392 | | 3 (0)| 00:00:01 |
| 12 | SORT UNIQUE | | 81 | 7776 | | | |
|* 13 | HASH JOIN | | 81 | 7776 | | 6 (17)| 00:00:01 |
| 14 | NESTED LOOPS OUTER | | 81 | 5913 | | 3 (34)| 00:00:01 |
| 15 | NESTED LOOPS OUTER | | 81 | 4860 | | 3 (34)| 00:00:01 |
| 16 | NESTED LOOPS OUTER | | 81 | 3807 | | 3 (34)| 00:00:01 |
| 17 | NESTED LOOPS OUTER | | 81 | 2754 | | 3 (34)| 00:00:01 |
| 18 | VIEW | index$_join$_009 | 81 | 1701 | | 3 (34)| 00:00:01 |
|* 19 | HASH JOIN | | | | | | |
| 20 | INDEX FAST FULL SCAN| IX_CB_ACC_NO | 81 | 1701 | | 1 (0)| 00:00:01 |
| 21 | INDEX FAST FULL SCAN| PK_CB_ACCOUNT | 81 | 1701 | | 1 (0)| 00:00:01 |
|* 22 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 13 | | 0 (0)| 00:00:01 |
|* 23 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 13 | | 0 (0)| 00:00:01 |
|* 24 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 13 | | 0 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | ACCOUNT_EXT_KEY | 1 | 13 | | 0 (0)| 00:00:01 |
|* 26 | TABLE ACCESS FULL | GV_ACCOUNTS | 87 | 2001 | | 3 (0)| 00:00:01 |
| 27 | TABLE ACCESS FULL | GV_BOOKS | 86600 | 2198K| | 104 (2)| 00:00:02 |
------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("ACCOUNTID"="ACCOUNTID")
9 - access("A"."ACCOUNTNO"="ACNTNO")
10 - filter("A"."DBLINK"='90')
13 - access("A"."ACCOUNTNO"="A"."ACCOUNT_NO")
19 - access(ROWID=ROWID)
22 - access("A"."ACCOUNT_ID"="E"."ACCOUNT_ID"(+) AND "E"."EXT_KEY"(+)='FEEMODE2')
23 - access("A"."ACCOUNT_ID"="B"."ACCOUNT_ID"(+) AND "B"."EXT_KEY"(+)='CALCINTR')
24 - access("A"."ACCOUNT_ID"="C"."ACCOUNT_ID"(+) AND "C"."EXT_KEY"(+)='DAYMODE')
25 - access("A"."ACCOUNT_ID"="D"."ACCOUNT_ID"(+) AND "D"."EXT_KEY"(+)='FEEMODE1')
26 - filter("A"."DBLINK"='90')

Delete 语句带有子查询的sql优化的更多相关文章

  1. 提高SQL查询效率(SQL优化)

    要提高SQL查询效率where语句条件的先后次序应如何写 http://blog.csdn.net/sforiz/article/details/5345359   我们要做到不但会写SQL,还要做到 ...

  2. 1. 元信息:Meta类 2. 基于对象查询的sql优化 3. 自定义:Group_Concat() 4. ajax前后台交互

    一.元信息 ''' 1. 元信息 1. Model类可以通过元信息类设置索引和排序信息 2. 元信息是在Model类中定义一个Meta子类 class Meta: # 自定义表名 db_table = ...

  3. SQL夯实基础(四):子查询及sql优化案例

    首先我们先明确一下sql语句的执行顺序,如下有前至后执行: (1)from  (2) on   (3) join  (4) where  (5)group by  (6) avg,sum...  (7 ...

  4. mysql的慢查询实战+sql优化

    背景:使用A电脑安装mysql,B电脑通过xshell方式连接,数据内容我都已经创建好,现在我已正常的进入到mysql中 步骤1:设置慢查询日志的超时时间,先查看日志存放路径查询慢日志的地址,因为有慢 ...

  5. SQL查询与SQL优化[姊妹篇.第四弹]

    在上一篇文章中,我们一起了解了关系模型与关系运算相关的知识,接下来我们一起谈谈,面对复杂的关系数据,我们如何来优化,SQL如何玩转更优呢? 在上一篇中抛出了4个关于优化方面的问题: 1.返回表中0.0 ...

  6. MySQL中DELETE语句嵌套子查询规则

    delete from table .....其中表名不能起别名 比如说:delete from table t where t.id = '1';(这条SQL语句将报错)

  7. mysql带有子查询的like查询

    SELECT * FROM by_app_categories WHERE c_name LIKE CONCAT('%', (SELECT `name` FROM b_catelist WHERE t ...

  8. MySQL5.6 怎样优化慢查询的SQL语句 -- SQL优化

    上篇:MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍 在实际的日志分析中,通常慢日志的log数量不少,同一时候同样的查询被记录的条数也会非常多.这里就须要怎样从慢日志查询中找到最有问题 ...

  9. oracle查询SQL优化相当重要

    如果表中的时间字段是索引,那么时间字段不要使用函数,函数会使索引失效. 例如: select * from mytable where trunc(createtime)=trunc(sysdate) ...

随机推荐

  1. scanf()和scanf_s()

    在最初的C语言中,原版的输入就是scanf("<格式化字符串>",<地址表>) ANSI C中没有scanf_s(),只有scanf(),scanf()在读 ...

  2. Jquery | 基础 | 慕课网 | (*选择器)

    原生JS var elements1 = document.getElementsByTagName('*'); JQ var elements2 = $("*"); <!D ...

  3. 关于BMP

    关于BMP位图的资料网上有很多,内容也比较基础.本文实现BMP位图的读取.显示.保存,并对一些重要的问题进行说明(包括字节对齐.内存中的存储顺序.调色板). BMP文件共包括文件头.信息头.调色板(位 ...

  4. STM32HAL库学习之前言

    HAL库:HAL 的全称是: Hardware Abstraction Layer (硬件抽象层) ,是ST最新推荐的库.包括基本库和扩展库(功能外展):三种编程模型(轮询.中断和 DMA) 灵活的回 ...

  5. PHP 讓 json_encode() 指定回傳格式

    PHP 回傳 JSON 很方便, 只要將資料經過 json_encode() 就解決了. 不過因為 PHP 自動轉換型別, 造成很多資料都習慣存成字串, 希望在輸出 JSON 的時候, 數字部份可以輸 ...

  6. 【C#】将数据库读出的数据转换为DataTable类型集合

    return View(ConverDataReaderToDataTable(reader)); // 静态方法public static DataTable ConverDataReaderToD ...

  7. 前端之CSS创建的样式

    CSS即层叠样式表,在创建时有以下几种样式: 1.内联样式(行内样式.行间样式): <标记 style=“属性:属性值:”></标记> 2.内部样式(嵌入式样式): <s ...

  8. Java-每日编程练习题③

    一.计算圆周率 中国古代数学家研究出了计算圆周率最简单的办法: PI=4/1-4/3+4/5-4/7+4/9-4/11+4/13-4/15+4/17...... 这个算式的结果会无限接近于圆周率的值, ...

  9. subprocess模块详解2

    1.call() 和run功能类似,都是接受一个列表里的参数. >>> import subprocess >>> a = subprocess.call([&qu ...

  10. css3 blur模糊解决ie6-ie9兼容

    css3 blur模糊是css3的新特性,但是不兼容ie6-ie9,以下代码可以解决此问题: filter: progid:DXImageTransform.Microsoft.Blur(Pixel ...