日期:2014-05-17  浏览次数:20746 次

【性能优化】求大神们帮看看这个存储过程怎么优化
说明:table1,table2,table3几个表都是几千万的数据量,性能上好象有点问题,对oracle不是很熟,求优化方案
begin
declare
    cursor cur_3 is select * from table1 
           where trunc(createtime) in 
           (select trunc(createtime) from table2  where........);
    type t_table is table of  table1%rowTYPE;
    c_table t_table;
begin
    open cur_3;
------------loop1
    loop
         fetch cur_3 bulk collect into c_table limit 1000;
         exit when c_table.count = 0;
        ---------------loop2
         for r in c_table.first..c_table.last loop
             select  字段1,字段2........
                    into 参数1.参数2......
                    from t_user where userid= c_table(r).UserID;
             -------------loop 3
            for de in (select * from table3 where **ID=c_table(r).**ID order by ******)  loop
                    ----又长又臭的业务表操作
            end loop;
         end loop;
    end loop;
    commit;
    EXCEPTION
       WHEN OTHERS THEN
       ROLLBACK;
    close cur_3;
end
------解决方案--------------------

------解决方案--------------------

目前运行有性能问题么?
------解决方案--------------------
如果是我来做的话。首先要看看循环里面出来的值域可不可以放到业务处理的条件中,把loop变成一次执行。。
如果业务处理必须的一次次操作的话,那只能循环执行。这种情况下就只能优化业务执行的效率了。。
你说的扫描,也要看表的字段数来衡量表的量级。。
如何效率高看具体执环境、业务执行语句的执行计划,没有绝对优化的sql,只有适合环境的sql
------解决方案--------------------
游标可以用bulk collect代替, for循环可以用for all或者merge into代替,我看你的脚本,可以优化成既不用游标,又不用任何for循环就能完成。
------解决方案--------------------
大数据量的运算,千万不要用游标,效率低得可怕。
直接用sql改写,必要时可以用临时表。
------解决方案--------------------
引用:
游标可以用bulk collect代替, for循环可以用for all或者merge into代替,我看你的脚本,可以优化成既不用游标,又不用任何for循环就能完成。

up.......
另外也可以考虑用ROWID来操作