我有一个基础表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;

解决方案 »

  1.   

    触发器没有问题,只是你的做法存在不妥的地方。
    你的程序看,你在被跟新的表ss,追加触发器,
    而且还进行GroupBy,这就不正确,因为假设你要更新1000条记录,根据你的GroupBy条件【road_id,road_now,road_speed】可能也就
    需要st的3条记录,本来就需要1003次更细就可以完成,而现在确变成了2000次处理,其中997次update会被
    其他数据所覆盖,这样的做法不赞成。建议你这样的需求使用程序逻辑去控制,在所有ss更新处理完后,在更新st表,能够快点,
    你在考虑一下,建议可能对你有用。
      

  2.   

    我也是这么想的,可是表ss是别人的应用程序更新数据的,我不知道如何在oracle判断ss被更新完,所以……你能不能更具体的说一下,最好弄个例子,谢谢!
      

  3.   

    我觉得从解决方法上,就存在偏差,
    因为触发器是要么在commit前执行,要么在commit后执行,都只是针对
    一条记录的处理,而你期望的是一个逻辑执行完毕后,在执行,在Oracle的触发器
    达到要求困难。还是应该在别人的程序里追加处理,如果实在不能追加,再提出,
    一起想办法,可以解决,但是比较麻烦。
      

  4.   

    循环是不必要的,增加了update次数。
    下面的修改请参考:
    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;