最近一个存储过程更新用了10多个小时还没执行完,最后还报了个ORA-01555: snapshot too old错误,真是郁闷。看了网上的介绍,有三种解决方案:

1、应用程序尽量避免巨表的漫长查询操作,改传统的cursor游标为bulk collect;

2、尽量程序中不要使用大事务量的增删改操作,同时记得及时commit;

3、加大undo表空间和加大undo的retention。

想想这样改了,如果不抱错,那也没什么用,算10多个小时的存储过程还怎么能用。再硬着头皮看了一下存储过程,看了是在更新的时候是这样写的
  update outtable o set  (c_code,f_test,f_test2,....)=
     (
       select c_code,sum(f_test) f_test,sum(f_test2)  f_test2 from innertable t
       where t.c_code=o.c_code
       group by  t.c_code
      );
一个存储过程中用好多这样的写法,看了好像也没什么问题,看了oracle的执行计划,里面的查询也用到了索引,不知道为什么这么慢。按理说每更新一条记录,传一个c_code进来,group by 也可以去掉,应该不会很慢。实在没办法了,那只有另想办法了,就是先把里面的查询放到一张临时表里。
在Oracle8i或以上版本中,可以创建以下两种临时表:
1 会话特有的临时表
    CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>)
    ON COMMIT PRESERVE ROWS;
  
2 事务特有的临时表
    CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>)
    ON COMMIT DELETE ROWS;
   CREATE GLOBAL TEMPORARY TABLE MyTempTable
先生建了个事务特有的临时表,然后再对c_code创建索引,先把查出来的记录放到临时表里,然后再从临时表里查询进行更新,意想不到的是这次10多分钟就执行完了。
     问题是解决了,但对oracle的执行机制不是很了解,特别是索引的应用,看来要恶补一下了。