【问题标题】:updating a very large oracle table更新一个非常大的 oracle 表
【发布时间】:2015-09-19 12:27:15
【问题描述】:

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

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

它运行了一个小时左右,然后我收到一个存档错误或 00257。 对分段运行更新或更好的 sql 命令有什么建议吗?

【问题讨论】:

  • 你可以尝试exists查询,但我认为Oracle的优化器足够聪明,可以使用相同的计划。你有id_conversion (id, newid)的索引吗?
  • 我有 id 索引但没有 newid。不明白为什么在 newid 上建立索引有好处。但是你是第二个提出这个建议的人,所以我开始担心了!

标签: sql oracle sql-update


【解决方案1】:

如果您的 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

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

【讨论】:

    【解决方案2】:

    我怀疑你能否在几秒钟内运行它。编写的查询需要更新所有 6000 万行。

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

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

    • 将数据复制到具有新值的新表中。
    • 截断原始表。
    • 将新数据插入旧表中。

    插入比更新快。

    【讨论】:

    • 它已经在 id 上建立了索引,不确定我是否理解在 newid 上建立索引的好处?
    • @TonyWolff 。 . .索引是查询的覆盖索引,所以不需要原始数据,只需要索引。这可以提高性能。
    • 这听起来很重要,但我不明白你能说得更详细一点
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2011-07-21
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多