merge into sql优化
今天网友说他的merge into sql跑了15分钟了还没有跑出数据,问我能不能优化一下,我让他把sql和sql的执行计划发过来
merge into F_Sal_P_Camp_Samp_Cust_Data A
using (select CUST_ID,
CUST_MNGR_ID,
ORGCODE From (
SELECT t.CUST_ID,
t.CUST_MNGR_ID,
t.ORGCODE,
ROW_NUMBER() OVER(PARTITION BY t.cust_id ORDER BY t.BELG_RELA_TYPE asc,t.open_percent DESC) AS RN
From F_Sal_P_Camp_Samp_Cust_Data a
INNER JOIN (
SELECT T.CUST_ID,T.CUST_MNGR_ID,T.BELG_RELA_TYPE,T.OPEN_PERCENT,OM.ORGSEQ,OM.ORGCODE
FROM O_F_PTY_P_CUST_BELG_INFO T
INNER JOIN OM_EMPLOYEE EMP
ON t.CUST_MNGR_ID = EMP.EMPCODE
and emp.empname not like '%虚拟%'
INNER JOIN AC_OPERATOR opr
ON emp.operatorid = opr.operatorid
AND opr.status IN ('running', 'openuse')
INNER JOIN OM_ORGANIZATION OM
ON EMP.ORGADMINID = OM.ORGID
) t ON A.CUST_ID=T.CUST_ID
where A.activity_id = '20150114-1003' AND t.orgseq like '.10001.'||'%'
and A.used_org = 'BS001'
and A.execute_man is null
) where rn = 1
) t1
on (A.CUST_ID = T1.cust_id AND A.activity_id = '20150114-1003')
when matched then
update
set A.execute_man = T1.CUST_MNGR_ID,
A.task_stat = '3',
a.Used_Org = T1.ORGCODE
WHERE A.activity_id = '20150114-1003'
5 - filter("RN"=1)
6 - filter(ROW_NUMBER() OVER ( PARTITION BY "T"."CUST_ID" ORDER BY
"T"."BELG_RELA_TYPE",INTERNAL_FUNCTION("T"."OPEN_PERCENT") DESC )<=1)
12 - filter("A"."USED_ORG"='BS001' AND "A"."EXECUTE_MAN" IS NULL)
13 - access("A"."ACTIVITY_ID"='20150114-1003')
15 - access("A"."CUST_ID"="T"."CUST_ID")
16 - filter("EMP"."EMPNAME" NOT LIKE '%虚拟%' AND "EMP"."EMPNAME" IS NOT NULL)
17 - access("T"."CUST_MNGR_ID"="EMP"."EMPCODE")
18 - filter("OPR"."STATUS"='openuse' OR "OPR"."STATUS"='running')
19 - access("EMP"."OPERATORID"="OPR"."OPERATORID")
20 - access("EMP"."ORGADMINID"="OM"."ORGID")
21 - filter("OM"."ORGSEQ" LIKE '.10001.%')
22 - access("A"."ACTIVITY_ID"='20150114-1003')
23 - filter("A"."CUST_ID"="CUST_ID")
看了这个执行计划,发现全都是NL连接,我让他查询相应sql返回的行数
F_Sal_P_Camp_Samp_Cust_Data 返回20w
select count(*) from O_F_PTY_P_CUST_BELG_INFO T; 369983
select count(*) from OM_EMPLOYEE EMP where emp.empname not like '%虚拟%; 6353
select count(*) from AC_OPERATOR opr where opr.status IN ('running', 'openuse'); 3234
select count(*) from OM_ORGANIZATION OM; 1079
发现返回的行数都不少,走NL连接一定有问题,应该走hash join,而且执行计划上看统计信息也是不对的
由于网友是开发没有dba权限,所以不能 重新统计信息,所以只能使用hint,添加了hint强制走hash,运行时间是19秒,网友说可以了,我在帮他看看
merge /*+ use_hash(A,t1) leading(A) */ into F_Sal_P_Camp_Samp_Cust_Data A
using (select CUST_ID,
CUST_MNGR_ID,
ORGCODE From (
SELECT /*+ use_hash(A,t) leading(a) */t.CUST_ID,
t.CUST_MNGR_ID,
t.ORGCODE,
ROW_NUMBER() OVER(PARTITION BY t.cust_id ORDER BY t.BELG_RELA_TYPE asc,t.open_percent DESC) AS RN
From F_Sal_P_Camp_Samp_Cust_Data a
INNER JOIN (
SELECT T.CUST_ID,T.CUST_MNGR_ID,T.BELG_RELA_TYPE,T.OPEN_PERCENT,OM.ORGSEQ,OM.ORGCODE
FROM O_F_PTY_P_CUST_BELG_INFO T
INNER JOIN OM_EMPLOYEE EMP
ON t.CUST_MNGR_ID = EMP.EMPCODE
and emp.empname not like '%虚拟%'
INNER JOIN AC_OPERATOR opr
ON emp.operatorid = opr.operatorid
AND opr.status IN ('running', 'openuse')
INNER JOIN OM_ORGANIZATION OM
ON EMP.ORGADMINID = OM.ORGID
) t ON A.CUST_ID=T.CUST_ID
where A.activity_id = '20150114-1003' AND t.orgseq like '.10001.'||'%'
and A.used_org = 'BS001'
and A.execute_man is null
) where rn = 1
) t1
on (A.CUST_ID = T1.cust_id AND A.activity_id = '20150114-1003')
when matched then
update
set A.execute_man = T1.CUST_MNGR_ID,
A.task_stat = '3',
a.Used_Org = T1.ORGCODE
WHERE A.activity_id = '20150114-1003'
这个sql中间嵌套了很多层,这是中间那层,这个sql跑了2:30秒
SELECT T.CUST_ID,T.CUST_MNGR_ID,T.BELG_RELA_TYPE,T.OPEN_PERCENT,OM.ORGSEQ,OM.ORGCODE
FROM O_F_PTY_P_CUST_BELG_INFO T
INNER JOIN OM_EMPLOYEE EMP
ON t.CUST_MNGR_ID = EMP.EMPCODE
and emp.empname not like '%虚拟%'
INNER JOIN AC_OPERATOR opr
ON emp.operatorid = opr.operatorid
AND opr.status IN ('running', 'openuse')
INNER JOIN OM_ORGANIZATION OM
ON EMP.ORGADMINID = OM.ORGID
select count(*) from O_F_PTY_P_CUST_BELG_INFO T; 369983
select count(*) from OM_EMPLOYEE EMP where emp.empname not like '%虚拟%; 6353
select count(*) from AC_OPERATOR opr where opr.status IN ('running', 'openuse'); 3234
select count(*) from OM_ORGANIZATION OM; 1079
看了这个执行计划,看了sql返回的行数,发现非常好,走的hash连接是对的,那为什么走的慢呢,因为所有的表走的都是全表扫描,没有走索引,但是能走索引的都是小表,没有影响,
真正有影响的是T表,T表30多w,而且没有筛选条件,只能改写sql了
with X as ( select /*+ materialize parallel(T,6) */ T.CUST_ID,T.CUST_MNGR_ID,T.BELG_RELA_TYPE,T.OPEN_PERCENT from O_F_PTY_P_CUST_BELG_INFO T)
SELECT X.CUST_ID,X.CUST_MNGR_ID,X.BELG_RELA_TYPE,X.OPEN_PERCENT,OM.ORGSEQ,OM.ORGCODE
FROM X
INNER JOIN OM_EMPLOYEE EMP
ON X.CUST_MNGR_ID = EMP.EMPCODE
and emp.empname not like '%虚拟%'
INNER JOIN AC_OPERATOR opr
ON emp.operatorid = opr.operatorid
AND opr.status IN ('running', 'openuse')
INNER JOIN OM_ORGANIZATION OM
ON EMP.ORGADMINID = OM.ORGID
sql改写之后跑了1分钟,快了好多
整个sql跑起来,在10秒左右,改到这里就可以了
本人qq 343548233,期待和各位交流,一起探讨sql,提高sql性能
merge into sql优化的更多相关文章
- ORACLE常用SQL优化hint语句
在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...
- 基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)
基于Oracle的SQL优化(社区万众期待数据库优化扛鼎巨著) 崔华 编 ISBN 978-7-121-21758-6 2014年1月出版 定价:128.00元 856页 16开 编辑推荐 本土O ...
- Oracle SQL优化一(常见方法)
1.表访问方式优化: a)普通表优先“Index Lookup 索引扫描”,避免全表扫描 大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表 ...
- sql优化点整理
此文是我最早开始sql优化至今整理的小知识点和经常遇到的问题,弄懂这些对优化大型的sql会有不少帮助 ---------------------------------使用了多余的外连接------- ...
- 大型系统开发sql优化总结(转)
Problem Description: 1.每个表的结构及主键索引情况 2.每个表的count(*)记录是多少 3.对于创建索引的列,索引的类型是什么?count(distinct indexcol ...
- Oracle 表三种连接方式(sql优化)
在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式: 嵌套循环(Nested Loops (NL)) (散列)哈希 ...
- sql优化--in和exists效率
系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists 修改方法如下: in的SQL语句 SELEC ...
- Oracle SQL优化[转]
Oracle SQL优化 1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化 ...
- 基于oracle的sql优化
[基于oracle的sql优化] 基于oracle的sql优化 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 一.编写初衷描述 在应有系统开发初期,由于数据库 ...
随机推荐
- Drawable(1)各种Drawable Resource介绍
简介 Drawable Resources(可绘资源) 是一系列可以在屏幕上被绘制的资源文件,它不只是图片,可以是 xml文件,在xml文件中配置各种绘制参数. 常见Drawable Resource ...
- sqliteExpert软件使用(创建数据库和表)
sqliteExpert是sqlite数据库的可视化操作软件,通过该软件可以进行可视化的创建数据库以及表,免去了复杂的建表语句.首先在下面地址下载该软件http://www.ddooo.com/sof ...
- [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.2.5
Show that matrices with distinct eigenvalues are dense in the space of all $n\times n$ matrices. (Us ...
- MEF学习小结 z
1.什么是MEF. MEF,全称是Managed Extensibility Framework.它是.NET Framework4.0的一个类库,其主要目的是为了创建可扩展的应用程序.按照官方说法就 ...
- oracle 的 regexp_substr()的用法
将字符串'1-2' 截取出来成1 .2,然后通过这两个值查出数据张三.李四 ,拼接起来成'张三-李四' oracle 语法 SELECT replace(WMSYS.WM_CONCAT(wrxm), ...
- python写的自动签到脚本。
等以后有时间补上. 附上代码: #! /usr/bin/env python # coding:utf-8 #-----------------------------------------学号和密 ...
- shell color
shell 输出着色 格式: echo "/033[字背景颜色;字体颜色m字符串/033[控制码" 如果单纯显示字体颜色可以固定控制码位0m. 格式: echo "/03 ...
- Java笔记(二十八)……IO流下 IO包中其他常用类以及编码表问题
PrintWriter打印流 Writer的子类,既可以接收字符流,也可以接收字节流,还可以接收文件名或者文件对象,非常方便 同时,还可以设置自动刷新以及保持原有格式写入各种文本类型的print方法 ...
- HDOJ-ACM1018(JAVA)
题意: 求n!的位数,0<n<10^7 思路:log10(1)+log10(2)+···+log10(n) = log10(n!) [题目的考点就在这吧] 解题: import jav ...
- 算法导论学习-Dynamic Programming
转载自:http://blog.csdn.net/speedme/article/details/24231197 1. 什么是动态规划 ------------------------------- ...