更新一个非常大的oracle表

时间:2015-09-19 12:27:15

标签: sql oracle sql-update

我有一个非常大的表,其中有60M行以id为索引,希望根据查找表id_conversion(1M行)填充每个记录的字段newid,其中包含id和newid,id为id。 我跑的时候

update people p set p.newid=(select l.newid from id_conversion l where l.id=p.id)

它运行了一个小时左右然后我得到了归档错误ora 00257。 是否有关于在部分中运行更新或更好的sql命令的建议?

3 个答案:

答案 0 :(得分:3)

如果你的update语句命中表的每一行,为了避免写入Oracle的撤销日志,那么最好运行create table as select查询,该查询将绕过所有撤消日志,这可能是您遇到的问题,因为它将影响记录在6000万行中。然后,您可以删除旧表并将新表重命名为旧表的名称。

类似的东西:

create table new_people as
select l.newid,
       p.col2,
       p.col3,
       p.col4,
       p.col5
  from people p
  join id_conversion l
    on p.id = l.id;

drop table people;

-- rebuild any constraints and indexes
-- from old people table to new people table

alter table new_people rename to people;

供参考,请阅读以下部分提示:http://www.dba-oracle.com/t_efficient_update_sql_dml_tips.htm

如果您基本上是在创建一个新表而不仅仅是更新表的某些行,那么它可能会证明是更快的方法。

答案 1 :(得分:2)

我怀疑你能在几秒钟内完成这项工作。您所写的查询需要更新所有6000万行。

我的第一个建议是在id_conversion(id, newid)上添加索引,以使子查询更有效。如果这没有用,那么批量更新可能是最好的方法。

我应该补充一下。因为您要更新所有行,所以采用以下方法可能会更快:

  • 使用新值将数据复制到新表中。
  • 截断原始表格。
  • 将新数据插入旧表格。

插入比更新更快。

答案 2 :(得分:2)

除了上面的答案,在这种情况下可能会更好,你应该知道MERGE语句 http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm 用于根据另一个表更新一个表,并且比根据select语句更新快得多