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

oracle批量插入导致的问题
有这样一个表,sms_to_be_sent,有几个进程来循环操作它。进程a负责判断有没有合适的数据,如果有的话生成一批数据,插入到这个表中。其他进程都是扫描这个表中有没有符合自己的数据,有的话取出这些数据,进行业务逻辑处理,同时把这些数据从表中删除掉。这些进程都是调用的存贮过程进行的数据库的操作。a每30秒执行一次数据库操作,其他进程要频繁的多。
      现在的问题是,当一次性插入的数据比较多时会执行时间过长。以前一次性插入7万条数据,执行的时间大概在120秒左右,现在的数据增大到了25万后,执行的时间竟然超过了半个小时,已经远远超过了可接受的范围!!我们做了实验,当把其他的进程都停掉只有a来执行时,25万条数据不到两分中就插完了。所以怀疑产生了锁等待的现象。可是,怎么解决呢,有谁碰到过相似的问题吗?
      进程a调用的存贮过程的大体结构如下:
      procedure   ScanTask(条件1)
      begin
                loop
                        if   条件1   不符合   then
                                    退出循环;
                        end   if;
                        SendTaskMsgToUsersByTaskId(条件1);//向sms_to_be_sent插入数据
                end   loop;
      end   procedure;
      SendTaskMsgToUsersByTaskId(条件)是向sms_to_be_sent批量插入数据数据的函数,根据 "条件 "的不同,每次的生成的数据的数量也不尽相同。
      现在的情况是loop循环了大概6-7次的样子,也就是SendTaskMsgToUsersByTaskId被调用了6,7次,有两次数据较多,分别为7万和十几万的样子。其他都较少,几千到一万的样子吧。
        该怎么解决阿,谢谢大家了,急啊!

------解决方案--------------------
建议不要一次性全部提交,多次,分开提交!!
如果数据量过大会受到oracle日志限制

------解决方案--------------------
如果是日志或者回滚段的限制。
应该不会在停止掉其他进程以后速度大幅提高。
简易楼主在插入数据的时候锁住表,并挂住其他进程。
这样既可以防止读进脏数据,也可以优化性能。
------解决方案--------------------
每30秒插入25万笔数据,可想每分钟也会删除几十万笔纪录。。。很想求教搂主你们对high water mark的处理。。。
这个案例,还建议搂主测算一下其他job的速度,我有点怀疑哪个删除数据的动作。