我有一个基础表ss,两分钟更新一次,我想让他在更新的同时求出他的total_speed,更新到另一张表st,但是应用程序在更新ss时,不到1000条数据竟然用了3分钟,而没有触发器的时候只有8秒,请高手指教!谢谢!
CREATE OR REPLACE TRIGGER ss_info
AFTER UPDATE ON ss
DECLARE
CURSOR cur_emp IS
SELECT road_id,sum(road_speed) AS total_speed ,road_now ,road_speed FROM ss GROUP BY road_id,road_now,road_speed;
v_emp cur_emp%rowtype;
BEGIN
FOR v_emp IN cur_emp LOOP
update st set road_speed=v_emp.total_speed,road_now=v_emp.road_now where road_id=v_emp.road_id;
END LOOP;
END;
CREATE OR REPLACE TRIGGER ss_info
AFTER UPDATE ON ss
DECLARE
CURSOR cur_emp IS
SELECT road_id,sum(road_speed) AS total_speed ,road_now ,road_speed FROM ss GROUP BY road_id,road_now,road_speed;
v_emp cur_emp%rowtype;
BEGIN
FOR v_emp IN cur_emp LOOP
update st set road_speed=v_emp.total_speed,road_now=v_emp.road_now where road_id=v_emp.road_id;
END LOOP;
END;
你的程序看,你在被跟新的表ss,追加触发器,
而且还进行GroupBy,这就不正确,因为假设你要更新1000条记录,根据你的GroupBy条件【road_id,road_now,road_speed】可能也就
需要st的3条记录,本来就需要1003次更细就可以完成,而现在确变成了2000次处理,其中997次update会被
其他数据所覆盖,这样的做法不赞成。建议你这样的需求使用程序逻辑去控制,在所有ss更新处理完后,在更新st表,能够快点,
你在考虑一下,建议可能对你有用。
因为触发器是要么在commit前执行,要么在commit后执行,都只是针对
一条记录的处理,而你期望的是一个逻辑执行完毕后,在执行,在Oracle的触发器
达到要求困难。还是应该在别人的程序里追加处理,如果实在不能追加,再提出,
一起想办法,可以解决,但是比较麻烦。
下面的修改请参考:
CREATE OR REPLACE TRIGGER ss_info
AFTER UPDATE ON ss BEGIN
update st a set (road_speed, road_now)
= (select sum(b.total_speed), b.road_now from ss
where b.road_id= a.road_id
group by road_id, road_now);
END;