当前位置: 首页 > news >正文

full join优化改写经验

1、问题

在项目中遇到这样的一个需求,从设备信息表和设备使用记录表中统计每个单位有效的设备信息和未被使用过的设备数量,开发商做成了full join方式,下面模拟一下场景,t1表是设备信息表,t2表是设备使用记录表,code是单位code。

with t as(select tt1.code,accountTotal,notused_cntfrom (select count(1) accountTotal,code from t1 group by code) tt1full join (select count(1) notused_cnt,t1.codefrom t1,t2where t1.id=t2.d1(+)and t2.d1 is nullgroup by t1.code) tt2on tt1.code=tt2.code)
select * from t;
计划如下:
1   #NSET2: [1046, 10->10, 100] 
2     #PRJT2: [1046, 10->10, 100]; exp_num(3), is_atom(FALSE) 
3       #HASH FULL JOIN2: [1046, 10->10, 100]; key_num(1); col_num(3); mix_aagr(0);mix_dist(0); MEM_USED(1617KB), DISK_USED(0KB) KEY(TT1.CODE=TT2.CODE)
4         #PRJT2: [368, 10->10, 48]; exp_num(2), is_atom(FALSE) 
5           #HAGR2: [368, 10->10, 48]; grp_num(1), sfun_num(1), MEM_USED(1653KB), DISK_USED(0KB), distinct_flag[0]; slave_empty(0) keys(T1.CODE)
6             #PARALLEL: [229, 2000000->2000000, 48]; scan_type(FULL) range_sfun_opt(0)
7               #CSCN2: [229, 2000000->2000000, 48]; INDEX33557263(T1); btr_scan(1)
8         #PRJT2: [676, 10->10, 52]; exp_num(2), is_atom(FALSE) 
9           #HAGR2: [676, 10->10, 52]; grp_num(1), sfun_num(1), MEM_USED(1653KB), DISK_USED(0KB), distinct_flag[0]; slave_empty(0) keys(T1.CODE)
10            #SLCT2: [672, 50000->1999000, 52]; T2.D1 IS NULL
11              #HASH RIGHT JOIN2: [606, 2000000->2999000, 52]; key_num(1); col_num(2); MEM_USED(44450KB), DISK_USED(0KB) KEY(T2.D1=T1.ID)
12                #PARALLEL: [105, 1000000->1000000, 4]; scan_type(FULL) range_sfun_opt(0)
13                  #SSCN: [105, 1000000->1000000, 4]; IDX_DM_T2(T2); btr_scan(1); is_global(1)
14                #PARALLEL: [231, 2000000->2000000, 52]; scan_type(FULL) range_sfun_opt(0)
15                  #CSCN2: [231, 2000000->2000000, 52]; INDEX33557263(T1); btr_scan(1)Statistics
-----------------------------------------------------------------0           data pages changed0           undo pages changed5331        logical reads0           physical reads0           redo size595         bytes sent to client534         bytes received from client1           roundtrips to/from client0           sorts (memory)0           sorts (disk)0           rows processed0           io wait time(ms)1219        exec time(ms)used time: 00:00:01.220. Execute id is 804

语句中可以分析到t2表存储着使用记录,使用一次就记录一次,t1表是有效的设备信息,再根据业务需求分析,这里主要是要从有效的信息中获取未使用的设备信息,t1表总数是有效的,T2表中没有t1表使用记录的设备数据就是未使用的。那么整个需求主要依赖于t1表,t2表作用是获取未使用的记录。所以根据需求描述,可以使用left join去实现。
Left join: 返回左表中所有的记录以及右表中连接字段相等的记录,右表不满足的记录记为null。
根据left join的了解,右表null的数据就是未使用的数据。那么整体上就可以优化改写了

2、改写

select code, count(1) accountTotal, sum(case when tt.d1 is null then 1 else 0 end) as notused_cntfrom (select t2.d1, t1.code from t1 left join (select distinct d1 from t2) t2on t1.id=t2.d1) tt
group by code
计划如下:
1   #NSET2: [683, 10->10, 56] 
2     #PRJT2: [683, 10->10, 56]; exp_num(3), is_atom(FALSE) 
3       #HAGR2: [683, 10->10, 56]; grp_num(1), sfun_num(2), MEM_USED(1653KB), DISK_USED(0KB), distinct_flag[0,0]; slave_empty(0) keys(DMTEMPVIEW_889194854.TMPCOL0)
4         #PRJT2: [542, 2000000->2000000, 56]; exp_num(2), is_atom(FALSE) 
5           #HASH RIGHT JOIN2: [542, 2000000->2000000, 56]; key_num(1); col_num(2); MEM_USED(1105KB), DISK_USED(0KB) KEY(T2.D1=T1.ID)
6             #PRJT2: [170, 1000->1000, 4]; exp_num(1), is_atom(FALSE) 
7               #DISTINCT: [170, 1000->1000, 4], MEM_USED(871KB), DISK_USED(0KB)
8                 #PARALLEL: [105, 1000000->1000000, 4]; scan_type(FULL) range_sfun_opt(0)
9                   #SSCN: [105, 1000000->1000000, 4]; IDX_DM_T2(T2); btr_scan(1); is_global(1)
10            #PARALLEL: [231, 2000000->2000000, 52]; scan_type(FULL) range_sfun_opt(0)
11              #CSCN2: [231, 2000000->2000000, 52]; INDEX33557263(T1); btr_scan(1)Statistics
-----------------------------------------------------------------0           data pages changed0           undo pages changed3223        logical reads0           physical reads0           redo size595         bytes sent to client359         bytes received from client1           roundtrips to/from client0           sorts (memory)0           sorts (disk)0           rows processed0           io wait time(ms)667         exec time(ms)used time: 667.566(ms). Execute id is 805.

改写后提交了1倍的性能。

3、小结

改写要从实际需求出发,了解其真正的需求,思考从更高效的方法去获取,这里主要思路是减少计算次数,提高效率,能一次性处理的就要一次性处理。

http://www.dtcms.com/a/560909.html

相关文章:

  • 软件测试:黑盒测试用例篇
  • 【Linux】Linux第一个小程序 - 进度条
  • ubuntu新增用户
  • 青州市网站建设长沙招聘网58同城招聘发布
  • 江苏中南建设集团网站是多少长沙互联网网站建设
  • 从零开始的云原生之旅(十一):压测实战:验证弹性伸缩效果
  • 民宿网站的建设wordpress gallery
  • 【开题答辩全过程】以 广州网红点打卡介绍网站为例,包含答辩的问题和答案
  • Taro 源码浅析
  • Chart.js 混合图:深度解析与应用技巧
  • redis 大key、热key优化技巧|空间存储优化|调优技巧(一)
  • 监视你的脚本:自动 Linux 活动审计
  • 15.1.2.linux常见操作用例
  • 【Java Web学习 | 第五篇】CSS(4) -盒子模型
  • ubuntu samba 快速安装启用
  • 【数据结构】用顺序表实现通讯录
  • cpp / c++零基础就业学习一站式学习平台
  • FreeRTOS(二)
  • 开源AI智能名片链动2+1模式S2B2C商城小程序商业化路径优化研究
  • 中国优秀的企业网站做搜狐网站页面
  • 【效率工具】EXCEL批注提取工具
  • Python openpyxl 设置Excel单元格公式和工作簿合并
  • 作文生成器网站北京seo招聘信息
  • 常州网站设计制作贵美商城网站的首页怎么做代码
  • 新媒体矩阵系统全景解析:赋能企业数字化营销的智能引擎
  • 多目标优化问题在适应度计算中的支配矩阵
  • 从零开始的云原生之旅(九):云原生的核心优势:自动弹性伸缩实战
  • 【Swift】LeetCode 240.搜索二维矩阵 II
  • 矩阵(板子)
  • 防火墙的内容补充