存储过程优化(并发思路)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
--im_cons_integral表为分区表按照org_no(单位编码)分区
---有效期历史数据处理
begin
  for cur in (select * from sgpm.o_org where org_type in ('04','05', '06')) loop
    insert into a_temp_ly_log
      select '有效期更新1', sysdate, '', cur.org_no, '', '' from dual; ---日志表
   
    update im_cons_integral a
       set a.expire_date =
           (period + 2) || '1231'
     where a.release_date < '20190501'
     and a.integral_type<>'09'
       and org_no = cur.org_no; ---5月前改成两年后的12月31日
              
    update im_cons_integral a
       set a.expire_date = to_char((add_months(to_date(release_date,
                                                       'yyyymmdd'),
                                               36) - 1),
                                   'yyyymmdd')
     where a.release_date >= '20190501'
     and a.integral_type<>'09'
       and org_no = cur.org_no; ---5月后加365*3天
   
    update a_temp_ly_log
       set END_DATE = sysdate
     where REMARK = cur.org_no
       and job_name = '有效期更新1';
    commit;
  end loop;
end;
 
开发反应效率很低从早上到晚上,只更新了完成了几个单位。
分析:
过程很简单就是一个日志表,记录自己更新完成了多少单位
然后两个update语句,im_cons_integral表数据量很大,每个分区有几百万到几千万数据不等,共396个分区。
两次update,im_cons_integral表扫描了两次分区的数据。
我们可以用casen when改写
  update im_cons_integral a
     set expire_date =
         (case when a.release_date < '20190501' then (period + 2) || '1231' else
          to_char((add_months(to_date(release_date, 'yyyymmdd'), 36) - 1),
                  'yyyymmdd'))
   where a.integral_type <> '09'
     and org_no = cur.org_no;
      
im_cons_integral表只需扫描一次。
最简单效率的方法就是全表更新,但是数据量太大,大事务,消耗大量undo资源。
 
 
我们可以对sgpm.o_org表的org_no进行分组,平均分配到4个表中。
create table sgpm.o_org1 as
select * from(
select org_no,row_number()over(order by org_no) num from sgpm.o_org
where org_type in ('04','05', '06')
) where num<100;
 
sgpm.o_org2
sgpm.o_org3
sgpm.o_org4
 
 
分表按照sgpm.o_org1-4同时执行四个过程,并且调整会话的并行
alter session force parallel dml parallel 4;
alter session force parallel query parallel 4;
数据库层面将undo调整为自动扩展且加入了一个数据文件,限制了5G大小,担心undo有压力。
 
begin
for cur in (select org_No from sgpm.o_org1) loop
  insert into a_temp_ly_log
      select '有效期更新1', sysdate, '', cur.org_no, '', '' from dual; ---日志表
       
  update im_cons_integral a
     set expire_date =
         (case when a.release_date < '20190501' then (period + 2) || '1231' else
          to_char((add_months(to_date(release_date, 'yyyymmdd'), 36) - 1),
                  'yyyymmdd'))
   where a.integral_type <> '09'
     and org_no = cur.org_no;
      
   update a_temp_ly_log
       set END_DATE = sysdate
     where REMARK = cur.org_no
       and job_name = '有效期更新1';
    commit;
end loop;
end;
/
1小时内就完成了所有单位的执行。

  

posted @   阿西吧li  阅读(310)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示