存储过程优化(并发思路)
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小时内就完成了所有单位的执行。 |
分类:
SQL优化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· 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