Oracle大单更新还是小批量更新?

时间:2016-09-23 07:40:00

标签: sql oracle oracle11g

我必须更新包含数百万行的表。更新非常简单,但由于它会修改数百万条记录,我想知道什么是最佳解决方案:

  • 执行一次大更新。
  • 使用批量收集/ forall语句更新表并以小批量提交更改。

我会选择第一个解决方案但是同事建议我分批进行,这样就不会阻止访问该表的其他会话。

那么哪种解决方案更好?

谢谢,

2 个答案:

答案 0 :(得分:1)

如果您的数据库有停机时间,那么最快的解决方案可能就像Tom Kyte所说:

create table new as select ... from old;
drop table old;
rename table new to old;

如果您没有窗口可以发生这种情况(可能会快几个数量级)并且阻止该表是不允许的,那么我建议您查看dbms_parallel_execute。 Oracle可以将表拆分为块并分别更新每个块。它比批量收集和更新forall更清洁,因为如果你想要一个具有附加条件and rowid between :start and :stop的大更新,你可以使用更新语句

begin
  dbms_parallel_execute.create_task ( task_name => 'MyTask');
  dbms_parallel_execute.create_chunks_by_rowid(
      task_name   => 'MyTask',
      table_owner => 'Me',
      table_name  => 'MyTable',
      by_row      => true,
      chunk_size  => 1000);
  dbms_parallel_execute.run_task(
      task_name      => 'MyTask',
      sql_stmt       => 'UPDATE mytable
                            set col = newval
                          where ...
                            and rowid between :start_id and :end_id',
      language_flag  => dbms_sql.native,
      parallel_level => 8);

然后,一旦完成,你检查状态:

dbms_parallel_execute.task_status(task_name => 'MyTask') = dbms_parallel_execute.FINISHED

如果成功,则删除任务。

dbms_parallel_execute.drop_task(task_name => 'MyTask');

答案 1 :(得分:0)

花费大量时间处理INSERT,UPDATE或DELETE语句或循环查询结果的程序。您将需要调查用于发出DML的FORALL语句,以及用于查询的BULK COLLECT INTO和RETURNING BULK COLLECT INTO子句。您可以查看此文档以用于您的目的。 http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/tuning.htm

这里有你的情况答案。

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::NO::P11_QUESTION_ID:6407993912330