加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

优化包含聚合运算的关联update

发布时间:2020-12-13 20:00:37 所属栏目:百科 来源:网络整理
导读:很多人开发人员不清楚 update 的原则,按照写代码的习惯写 update : update a set a.value=(select count(1) from b where a.col=b.col); 实际上,这个 update 语句大概运行逻辑是这样的: for c in (select * from a) loop select count(1) from b where b

很多人开发人员不清楚update的原则,按照写代码的习惯写update

update a set a.value=(select count(1) from b where a.col=b.col);

实际上,这个update语句大概运行逻辑是这样的:

for c in (select * from a) loop

select count(1) from b where b.col=c.col;

update ......

end loop;

遇到这种情况,常用的解决方法有两种:

1. 创建一个临时表,把b表的数据做好聚合后放到临时表上,这样就可以把对b表的扫描转换为更小的临时表的扫描;
2. merge代替update

SQL> merge into DM_REPORT_MV_LINE_EQUIPMENT T
2 using (SELECT RO.MRID,COUNT(C.ID) AS DLFJX_COUNT
3 FROM DM_FL_REGION_LINE RL,
4 DM_FL_LINE_SUBSTATION LS,
5 DM_FL_OBJECT RO,
6 DM_FL_SUBSTATION_DLFJX SD,
7 DM_INSTALL_HISTORY H,
8 DM_A_COMMON C
9 WHERE RL.OBJECT_A_ID = RO.ID
10 AND RL.OBJECT_B_ID = LS.OBJECT_A_ID
11 AND LS.OBJECT_B_ID = SD.ID
12 AND SD.ID = H.FUNCTION_ID
13 AND H.ASSET_ID = C.ID
14 GROUP BY RO.MRID) L
15 on (T.ID = L.MRID)
16 when matched then
17 update set T.DLFJX_COUNT = L.DLFJX_COUNT;

20 行已合并。

已用时间: 00: 00: 00.92

-----------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
0 recursive calls
24 db block gets
69072 consistent gets
0 physical reads
0 redo size
551 bytes sent via SQL*Net to client
1084 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
20 rows processed

SQL> UPDATE DM_REPORT_MV_LINE_EQUIPMENT T
2 SET T.DLFJX_COUNT = (SELECT L.DLFJX_COUNT
3 FROM (SELECT RO.MRID,COUNT(C.ID) AS DLFJX_COUNT
4 FROM DM_FL_REGION_LINE RL,
5 DM_FL_LINE_SUBSTATION LS,
6 DM_FL_OBJECT RO,
7 DM_FL_SUBSTATION_DLFJX SD,
8 DM_INSTALL_HISTORY H,
9 DM_A_COMMON C
10 WHERE RL.OBJECT_A_ID = RO.ID
11 AND RL.OBJECT_B_ID = LS.OBJECT_A_ID
12 AND LS.OBJECT_B_ID = SD.ID
13 AND SD.ID = H.FUNCTION_ID
14 AND H.ASSET_ID = C.ID
15 GROUP BY RO.MRID) L
16 WHERE T.ID = L.MRID);

已更新20行。

已用时间: 00: 00: 10.26

--------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
0 recursive calls
42 db block gets
227902 consistent gets
0 physical reads
5080 redo size
551 bytes sent via SQL*Net to client
1422 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
21 sorts (memory)
0 sorts (disk)
20 rows processed

merge的原理是直接关联两个记录集,等到关联结果后直接基于关联结果进行更新,它对每个表只需扫描一次。update改为merge很简单,但是带很大的性能收益。

10046跟踪:

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.04 0.03 0 0 0 0
Execute 1 1.68 1.68 0 69072 22 20
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 1.73 1.71 0 69072 22 20

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.00 0 0 0 0
Execute 1 21.18 21.20 0 227902 44 20
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 21.20 21.21 0 227902 44 20

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读