在Oracle诸多类型的错误中,ORA-01555 snapshot too old是最教人莫名其妙的。它的直接表征是查询操作需要读取的回滚段信息被覆盖掉而导致无法实现一致性读。Oracle提供的帮助文档指导用户通过扩大回滚段或者 是增加undo_retention时间来解决问题——对大多数案例而言,这两个方案有点大动干戈:因为优化相关的SQL语句就可以找到问题的症结:尤其 是当你的存储过程里存在对游标的操作时,就更要看看语句逻辑上有没有改进的空间。首先,是不是可以把打开游标后的循环内部操作再精简一些呢?因为游标打开的时间越长,发生ORA-01555的概率就越高。其次,有的游标涉及的表多、数据量大,直接通过复杂的SQL查询语句定义游标,会导致游标运行效率低下 (特别是没有索引的时候),这也是ORA-01555滋生的温床——这样的话,可以先将这些待处理的数据存入一张临时表,再以游标形式打开这张临时表,效率就提高很多了。这就好比一个穿着底有锉的鞋子的人不小心刮坏了精致的地板,最经济的办法是换一双鞋,而不是立刻忙着改进地板的材料。