分类: Oracle

2017-04-13 10:55:07

 
说说背景:开发有个需求,需要对新加的一个字段根据特定的业务逻辑更新数据。
TPS_TRADE表数据有4000多万,TPS_EXTERNAL_REF表3600多万,TPS_ACCOUNT表8200多万。
开发的SQL如下:
UPDATE TPS_TRADE a 
SET a.OPEN_LOT_QTY = 

SELECT a.trade_qty - nvl(sum(c.TRADE_QTY),0) 
FROM TPS_TRADE c, 
TPS_EXTERNAL_REF d 
WHERE c.id=d.TPS_TRADE_FK_ID 
AND c.BUY_SELL='S' 
AND d.value1 = a.BO_TRADE_NUM 
AND d.EXT_REF_TYPE='LINKED_LOT_ID' 
AND c.TRADE_STATUS='ACTV' 

WHERE EXISTS 

SELECT 1 FROM TPS_ACCOUNT b 
WHERE b.TPS_TRADE_FK_ID=a.id 
AND b.ACCOUNT_MNEMONIC IN ('CTSCCLH','CTSRNHT','CTSRTHT','CTSRYCP','CTSCAU','CTSCCB','CTSCCLO','CTSCCR','CTSCGG','CTSCOA','CTSCSL1','CTSCSL2','CTSCSRI',
'CTSCUK','CTSFAUS','CTSFCHS','CTSFDES','CTSFEBT','CTSFFIS','CTSFJPS','CTSFNLS','CTSFSES','CTSFUKG','CTSRFAD','CTSRFHL','CTSRFRB','CTSRGAR','CTSRGFI','CTSRGTY',
'CTSRM15','CTSRMAR','CTSRMFI','CTSRMFL','CTSROTR','CTSRSTP','CTSRT30','CTSRTIP','CTSRVAD','CTSRYAC','CTSRYAR','CTSRYFI','CTSRYS1','CTSRYTY')

AND a.BUY_SELL='B' 
AND a.TRADE_STATUS='ACTV' 
AND a.OPEN_LOT_QTY IS NULL;

这条SQL执行计划如下:

可以看到COST非常高,而且还有大表的全表扫描。 执行时间要4个多小时。

MERGE INTO 改写的SQL:
MERGE INTO TPS_TRADE a 
USING TPS_ACCOUNT b
ON (a.ID = b.TPS_TRADE_FK_ID AND b.ACCOUNT_MNEMONIC IN ('CTSCCLH','CTSRNHT','CTSRTHT','CTSRYCP','CTSCAU','CTSCCB',
                                                       'CTSCCLO','CTSCCR','CTSCGG','CTSCOA','CTSCSL1','CTSCSL2',
                                                       'CTSCSRI','CTSCUK','CTSFAUS','CTSFCHS','CTSFDES','CTSFEBT',
                                                       'CTSFFIS','CTSFJPS','CTSFNLS','CTSFSES','CTSFUKG','CTSRFAD',
                                                       'CTSRFHL','CTSRFRB','CTSRGAR','CTSRGFI','CTSRGTY','CTSRM15',
                                                       'CTSRMAR','CTSRMFI','CTSRMFL','CTSROTR','CTSRSTP','CTSRT30',
                                                       'CTSRTIP','CTSRVAD','CTSRYAC','CTSRYAR','CTSRYFI','CTSRYS1','CTSRYTY')
AND a.BUY_SELL='B' 
AND a.TRADE_STATUS='ACTV')
WHEN MATCHED THEN
UPDATE SET OPEN_LOT_QTY =

SELECT a.trade_qty - nvl(sum(c.TRADE_QTY),0) 
FROM TPS_TRADE c, 
TPS_EXTERNAL_REF d 
WHERE c.id=d.TPS_TRADE_FK_ID 
AND c.BUY_SELL='S' 
AND d.value1 = a.BO_TRADE_NUM 
AND d.EXT_REF_TYPE='LINKED_LOT_ID' 
AND c.TRADE_STATUS='ACTV' 
) ;

执行计划:

可以看到COST下降到86367,也消除了全表扫描。执行时间更是下降到了秒级,只需要不到2秒的时间。

在SQL改写的时候,首先要遵循的就是逻辑不能变,在开发写的SQL中有个限制条件是a.OPEN_LOT_QTY IS NULL,而在改写成MERGE INTO方法时,我也是把这个条件放在USING的ON条件里的,这样是不可以的,报下面的错误:
ORA-38104: Columns referenced in the ON Clause cannot be updated: "A"."OPEN_LOT_QTY"
38104. 00000 -  "Columns referenced in the ON Clause cannot be updated: %s"
*Cause:    LHS of UPDATE SET contains the columns referenced in the ON Clause

根据错误提示可以看到,ON条件里的列是不能被UPDATE的。 后来经过确认,发现这张表里所有的OPEN_LOT_QTY都是NULL的,所以就把这个条件从ON里去掉,完成优化。

merge into优化sql(转)的更多相关文章

  1. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  2. 应用索引技术优化SQL 语句(转)

    原文出处 一.前言 很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句.这类SQL语句性能不好的首要原因是缺乏高效的索引.没有索引除了导致语句本身运行速度慢外,更是导致 ...

  3. 无法收集统计信息,怎样优化SQL。

    特殊情况如下 客户的统计信息是固定的,没办法收集统计信息 . SQL profile 是最后考虑方案,因为同样写法sql 比较多,几十条. Parallle 并行客户一般不考虑接受,OLTP 系统. ...

  4. advisor调优工具优化sql(基于sql_id)

    advisor调优工具优化sql(基于sql_id) 问题背景:客户反馈数据库迁移后cpu负载激增,帮忙查看原因 解决思路:1> 查看问题系统发现有大量的latch: cache buffers ...

  5. 如何用 SQL Tuning Advisor (STA) 优化SQL语句

    在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...

  6. SQL常见优化Sql查询性能的方法有哪些?

    常见优化Sql查询性能的方法有哪些? 1.查询条件减少使用函数,避免全表扫描 2.减少不必要的表连接 3.有些数据操作的业务逻辑可以放到应用层进行实现 4.可以使用with as 5.使用“临时表”暂 ...

  7. mysql优化SQL语句的一般步骤及常用方法

    一.优化SQL语句的一般步骤 1. 通过show status命令了解各种SQL的执行频率 mysqladmin extended-status 或: show [session|global]sta ...

  8. paip.索引优化---sql distict—order by 法

    paip.索引优化---sql distict—order by 法 作者Attilax ,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...

  9. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

随机推荐

  1. CF401D 【Roman and Numbers】

    题意将n(n<=10^18)的各位数字重新排列(不允许有前导零)  求  可以构造几个mod m等于0的数字解法状压f[S][k] 表示选用的位数集合为S,mod m 为k的方案数注意不能有前导 ...

  2. 每位架构师都应该熟知的 10 个 SOA 设计模式

    这 10 个 SOA 设计模式是如此之重要,其应用是如此之广泛,以至于它们都有些显而易见了. 1. 服务无关 服务无关实现对多种业务通用的逻辑.将服务无关的逻辑分离成离散的服务以方便服务的重用和整合. ...

  3. 结合Python代码介绍音符起始点检测 (onset detection)

    本文由 meelo 原创,请务必以链接形式注明 本文地址 音符起始点检测介绍 音符起始点检测(onset detection)是音乐信号处理中非常重要的一个算法.节拍和速度(tempo)的检测都会基于 ...

  4. N的阶乘末尾有多少个0

    N的阶乘(N!)中的末尾有多少个0? N的阶乘可以分解为: 2的X次方,3的Y次方,4的5次Z方,.....的成绩.由于10 = 2 * 5,所以M只能和X和Z有关,每一对2和5相乘就可以得到一个10 ...

  5. 【LOJ】#2031. 「SDOI2016」数字配对

    题解 这个图是个二分图,因为如果有一个奇环的话,我们会发现一个数变成另一个数要乘上个数不同的质数,显然不可能 然后我们发现这个不是求最大流,而是问一定价值的情况下最大流是多少,二分一个流量,加上一条边 ...

  6. Kibana部署及配置(四)

    一.Kibana安装 Kibana 是为 Elasticsearch 设计的开源分析和可视化平台.你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互.你可 ...

  7. 在android studio中集成javah, ndk-build进行JNI开发

    最近在搞一个android上控制LED灯闪烁的功能,用到了串口编程,搜索了一下,发现Google发布了一个demo,android-serialport-api.有现成的代码和APK,要想自己改JNI ...

  8. tomcat如何利用waf进行防护

    近期某一实验室遇到一个问题:web环境是windows+tomcat+mysql,检测到cookie注入,此时又不想修改代码.此时两种方案进行解决: 1.利用安软(waf)类进行检测防御.这里国内主要 ...

  9. [leetcode DP]91. Decode Ways

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  10. 机器学习之路:python k近邻回归 预测波士顿房价

    python3 学习机器学习api 使用两种k近邻回归模型 分别是 平均k近邻回归 和 距离加权k近邻回归 进行预测 git: https://github.com/linyi0604/Machine ...