需求:

  小表数据量20w条左右,大表数据量在4kw条左右,需要根据大表筛选出150w条左右的数据并关联更新小表中5k左右的数据。

性能问题:

对筛选条件中涉及的字段加index后,如下常规的update语句仍耗时半小时左右。

  UPDATE WMOCDCREPORT.DM_WM_TRADINGALL A
SET
(
A.RELATIONSHIPNO,
A.PACKAGE
)
=
(SELECT
B.RELATIONSHIPNO,
CASE
WHEN (B.SEGMENTCODE=''
OR B.SEGMENTCODE =''
OR B.SEGMENTCODE =''
OR B.SEGMENTCODE ='')
THEN 'BC'
WHEN (B.SEGMENTCODE='')
THEN 'PW'
WHEN (B.SEGMENTCODE='')
THEN 'MM'
WHEN (B.SEGMENTCODE='')
THEN 'EB'
WHEN (B.SEGMENTCODE='')
THEN 'PB'
ELSE B.SEGMENTCODE
END
FROM DATACORE.DF_CUST_HISTORY B
WHERE B.ACCOUNT_NO=A.SETTLEMENTACCOUNT
AND B.DATA_DATE = '2018-11-30'
AND rownum = 1
)
WHERE A.MONTH = 'SEP'
AND A.DATA_DATE = '2018-09-30'
AND EXISTS
(
SELECT 1 FROM DATACORE.DF_CUST_HISTORY C
WHERE C.ACCOUNT_NO=A.SETTLEMENTACCOUNT
AND C.DATA_DATE = '2018-11-30'
);

经过数次搜索,发现同关联更新有关的技术博客基本上是更新大表数据,比如here.(使用批量更新)。

也分析过执行计划,同预想的性能瓶颈一样,主要由以下两个方面造成

(1) DATACORE.DF_CUST_HISTORY数据量太大,本想将某一天的数据select出来提前插入到一张表中,但估计效果不会太明显,因为插入150w条数据本身也会耗时很长。

(2) 需要更新5k条数据,且每条数据需要到150w条数据中做关联查询(时间主要耗在这)。

性能优化:

小表5k,大表150w,理所应当想到采用join的方式并保留小表中的数据。接下来是怎么把join后的数据更新到小表中(不用update)?merge into!

这里还涉及到一个小问题,merge into中的on条件需要保证一一对应,而大表中很可能出现重复的ACCOUNT_NO,所以需要排重,怎么做?用partition by !

另外,关于join中on条件和where条件的比较

优化后的sql(运行时间8-10s):

merge into wmocdcreport.dm_wm_tradingall a
using (
select
t.rid,
t.settlementaccount,
tx.relationshipno,
case
when (tx.segmentcode = '' or tx.segmentcode = '' or
tx.segmentcode = '' or tx.segmentcode = '') then
'BC'
when (tx.segmentcode = '') then
'PW'
when (tx.segmentcode = '') then
'MM'
when (tx.segmentcode = '') then
'EB'
when (tx.segmentcode = '') then
'PB'
else
tx.segmentcode
end as package
from (
select rowid rid,
dwt.settlementaccount
from wmocdcreport.dm_wm_tradingall dwt
where dwt.month = 'SEP'
and dwt.data_date = '2018-09-30'
) t
inner join
(
select row_number() over (partition by c.account_no order by c.relationshipno) seq,
c.account_no,
c.relationshipno,
c.segmentcode
from datacore.df_cust_history c
where c.data_date = '2018-11-30'
) tx
on tx.account_no = t.settlementaccount and tx.seq = 1
) b on (a.rowid = b.rid)
when matched then
update set a.relationshipno = b.relationshipno,
a.package = b.package;

Oracle SQL性能优化 - 根据大表关联更新小表的更多相关文章

  1. Oracle SQL性能优化技巧大总结

    http://wenku.baidu.com/link?url=liS0_3fAyX2uXF5MAEQxMOj3YIY4UCcQM4gPfPzHfFcHBXuJTE8rANrwu6GXwdzbmvdV ...

  2. Oracle SQL 性能优化技巧

    Select语句完整的执行顺序: SQL Select语句完整的执行顺序: 1. from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将 ...

  3. ORACLE SQL性能优化(全)

    ORACLE SQL性能优化(全) http://wenku.baidu.com/view/b2aaba3887c24028915fc337.html

  4. Oracle SQL性能优化

    (1)      选择最有效率的表名顺序(只在基于规则的优化器中有效):ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table) ...

  5. Oracle SQL性能优化(转)

    (1)      选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table ...

  6. <转>Oracle SQL性能优化

    原文链接:http://www.cnblogs.com/rootq/archive/2008/11/17/1334727.html (1)      选择最有效率的表名顺序(只在基于规则的优化器中有效 ...

  7. oracle sql 性能 优化

    目录[-] (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效):ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table ...

  8. [转]Oracle SQL性能优化

    本文转自:http://www.cnblogs.com/rootq/archive/2008/11/17/1334727.html (1)      选择最有效率的表名顺序(只在基于规则的优化器中有效 ...

  9. Oracle SQL性能优化总结

    1. SQL语句执行步骤 语法分析> 语义分析> 视图转换 >表达式转换> 选择优化器 >选择连接方式 >选择连接顺序 >选择数据的搜索路径 >运行“执 ...

随机推荐

  1. Python之访问set

    dict的作用是建立一组 key 和一组 value 的映射关系,dict的key是不能重复的. 有的时候,我们只想要 dict 的 key,不关心 key 对应的 value,目的就是保证这个集合的 ...

  2. Array拼接字符串

    原文发布时间为:2011-01-12 -- 来源于本人的百度文章 [由搬家工具导入] Array拼接字符串本来就是一种投机取巧的无聊玩意,来源是IE6对字符串的+实现错误一般情况下,如果是语义性的字符 ...

  3. 搞定vim的窗口操作

    最近在给学生演示数据结构代码时,发现用一般的方法总会有不方便,如果使用ide又觉得太浪费了,后来觉得用vim就够了,使用buffer总会需要页面调来跳出,学生看起来容易迷糊.所以就研究了下vim的窗口 ...

  4. s 中日期 转换成时间戳 例如2013-08-30 转换为时间戳

    以前遇到过一个关于时间戳的问题,为了不被大家鄙视,先说一下概念. 具体时间戳怎么定义的我也不清楚,但百度百科中有这么一句:“时间戳是自 1970 年 1 月 1 日(00:00:00 GMT)至当前时 ...

  5. LeetCode OJ-- Integer to Roman @

    @表示有更优解法 https://oj.leetcode.com/problems/integer-to-roman/ 将自然数,转换成罗马数字,输入范围为 1 ~ 3999,因为罗马数没有0. 用一 ...

  6. LeetCode OJ--Combinations *

    https://oj.leetcode.com/problems/combinations/ 给一个集合,求个数为k的所有子集 递归调用,深搜 class Solution { public: vec ...

  7. List集合使用注意的问题

    在做自动保存草稿的功能遇到集合数据的问题,先贴自动保存草稿的代码 /** * 每5 秒保存一次草稿 */private void startDraftTimerTask(){ if (draftTim ...

  8. Codeforces 898 C.Phone Numbers-STL(map+set+vector)

    C. Phone Numbers   time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. Akka Stream之Graph

    最近在项目中需要实现图的一些操作,因此,初步考虑使用Akka Stream的Graph实现.从而学习了下: 一.介绍 我们知道在Akka Stream中有三种简单的线性数据流操作:Source/Flo ...

  10. 创建maven项目是其中的group id和artifact id怎么填写

    groupid和artifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找. groupId一般分为多个段 ...