求帮忙优化,有关于存储过程使用游标

干饭人之路 2014-07-20 03:24:38
1、存储过程,如下:
create or replace procedure insert_oneday2 is
vr_begintime s_job_log.begin_time%type;
vr_endtime s_job_log.begin_time%type;
vr_onedayss oneday.onedayss%type;
CURSOR s_ss is select onedayss from oneday order by onedayss asc;--基础表
CURSOR s_bd is select begin_time,end_time from s_job_log s where isdate(s.begin_time)=1 and isdate(s.end_time)=1 and substr(s.begin_time,1,10)='2014/07/17' order by begin_time asc;--基础日期
begin
update oneday2 o2 set o2.cnt=0 ;
commit;
open s_ss;
loop
fetch s_ss into vr_onedayss;
exit when s_ss%notfound;
begin
open s_bd;
loop
fetch s_bd into vr_begintime,vr_endtime;
exit when s_bd%notfound;
begin
update oneday2 o2 set o2.cnt=o2.cnt+(case when ((vr_onedayss >=vr_begintime) and (vr_onedayss<=vr_endtime)) then 1 else 0 end)
where o2.onedayss=vr_onedayss;
commit;
end;
end loop;
close s_bd;--关闭游标
end;
end loop;
close s_ss;--关闭游标
end insert_oneday2;
-------------------
2、说明:
2.1 oneday和oneday2表结构相同,都只有两个字段onedayss和cnt,两个表的初始化数据j记录也完全一致,两个表都有8640条记录,都是存放的2014/07/17当前从0点开始岛24点,每隔10秒一条记录,如:
2014/07/17 00:00:00 0
2014/07/17 00:00:10 0
......
2014/07/17 16:27:50 0
2014/07/17 16:28:00 0
2014/07/17 16:28:10 0
2014/07/17 16:28:20 0
2014/07/17 16:28:30 0
2014/07/17 16:28:40 0
......
2014/07/17 23:59:40 0
2014/07/17 23:59:50 0
---------------
2.2 s_job_info_log表是一个job运行日志表, 记录了每天某一个job在两个时间begin_time和end_time中的运行日志,s_job_info_log大约有2800条记录;
2.3 上面的存储过程insert_oneday2 主要完成如下功能,
当oneday中某一个记录其字段onedayss(比如:2014/07/17 16:27:20),在s_job_info的一条记录中的begin_time和end_time之间时,则该记录的cnt=cnt+1;
如此循环,直到所有oneday2表中的记录都在s_job_info中比较一偏,无遗漏,那么oneday2表中就记录了某一个时间点(时间点之间间隔10秒)有多少个job在运行。
但是由于该存储过程insert_oneday2 要遍历8400*2800=23520000次,执行23520000次update,执行效率极为低下,请教各位有没有什么好的优化方案。
...全文
132 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiyiwan 2014-07-20
  • 打赏
  • 举报
回复
原来昨晚那个是为了构造这个表。 这个更新如果换一种思路会变得很简单,sql和程序语言的思想是不一样的,更需要从集合处理方面优先考虑,假设Log表中的结果是这样,那么问题就变成在某个特定的时间点有多少个begin end time.
SQL> select to_char(begin_time,'yyyymmdd HH24:MI:SS') begin_time,
  2  to_char(end_time,'yyyymmdd HH24:MI:SS')  end_time from s_job_log s
  3  /
 
BEGIN_TIME        END_TIME
----------------- -----------------
20140717 12:00:01 20140717 13:00:01
20140717 12:00:01 20140717 22:00:01
20140717 02:00:01 20140717 21:00:01
很容易得到如下结果集,
SELECT t1.onedayss, COUNT(l.rowid) cnt
  FROM oneday t1, s_job_log l
 WHERE to_date(t1.onedayss, 'yyyymmdd HH24:MI:SS') BETWEEN l.begin_time(+) AND l.end_time(+)
 GROUP BY t1.onedayss 
直接insert到oneday2表中即可,不需要事先构造oneday2表再更新。

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧