有大约70万条数据需要更新,用游标的话效率会很低吗?

时间:2020-12-05 23:33:09
有一张业务表tmp_stg_serv记录有业务编号serv_id和地址stid等信息,有70多万条数据;另外有一个业务清理表tmp_imp_serv,记录的是手工清理后的业务编号(serv_id)、地址(stid)以及清理时间(imp_date)等信息;还有一张业务历史记录表tmp_hist_serv,记录有业务编号(serv_id)和业务发生了变化的时间(start_date)等信息。

由于不清楚业务清理是发生在业务变动前还是变动后,所以现在需要根据tmp_hist_serv表里最近的start_time来与imp_time作比较以判断业务清理是在前还是在后。如果发现业务清理发生在最新变动的业务之后,那么就要用tmp_imp_serv表里的stid覆盖tmp_stg_serv表的stid,否则就不覆盖。用游标实现过程如下:


declare
v_date date; 
cursor cur_servid is
select serv_id from tmp_stg_serv;
v_servid number(10);

begin
open cur_servid;
loop
fetch cur_servid into v_servid;
exit when cur_servid%notfound;

select ta.start_date into v_date from 
(select * from tmp_hist_serv 
where serv_id=v_servid order by start_date desc) ta
where rownum=1

update tmp_stg_serv ss set (ss.stid,ss.addr_grade,ss.addrid_source)=
(select sa.stid,sa.st_grade,3 from tmp_imp_serv sa 
where sa.serv_id=ss.serv_id)
where exists(select 1 from tmp_imp_serv sa 
where sa.serv_id=v_servid and (sa.imp_date-v_date)>0)  --确定业务变动发生在清理后,更新stid等信息

end loop;
close cur_servid;
end;


不知道用上面的方法实现的话效率会不会很低?大侠们有没有好的改进办法?多谢了!

9 个解决方案

#1


游标的效率不会太高的。

#2


引用 1 楼 lzd_83 的回复:
游标的效率不会太高的。

呃,那有改进的办法吗?

#3


游标定位70W 条数据,PGA都占满了吧

#4


引用 3 楼 sky_4k_ppm 的回复:
游标定位70W 条数据,PGA都占满了吧

呃,这也是个问题,怎么解决呢?

#5


还有人帮忙看下吗

#6


可以考虑用批处理 forall等

#7


没看,所有update 都可以用update语句搞定
      所有insert or update 都可以用merge搞定。 

#8


数据比较多的情况下用游标进行更新的话,速度会很慢而且很占内存。因为游标是把数据全部取出后,然后再逐条处理。

#9


当然要先考虑用SQL直接更新了!
游标太慢了,耗时!

#1


游标的效率不会太高的。

#2


引用 1 楼 lzd_83 的回复:
游标的效率不会太高的。

呃,那有改进的办法吗?

#3


游标定位70W 条数据,PGA都占满了吧

#4


引用 3 楼 sky_4k_ppm 的回复:
游标定位70W 条数据,PGA都占满了吧

呃,这也是个问题,怎么解决呢?

#5


还有人帮忙看下吗

#6


可以考虑用批处理 forall等

#7


没看,所有update 都可以用update语句搞定
      所有insert or update 都可以用merge搞定。 

#8


数据比较多的情况下用游标进行更新的话,速度会很慢而且很占内存。因为游标是把数据全部取出后,然后再逐条处理。

#9


当然要先考虑用SQL直接更新了!
游标太慢了,耗时!