更新1000万行需要帮助

时间:2013-04-29 21:24:24

标签: oracle

我需要用表B中的2列更新表A. (表A,B只有两列共同点 - col1a,co11b :: col2a,col2b

示例脚本:我想用col1b更新所有col1a值,其中col2a = col2b

UPDATE a
   SET col1a = (SELECT col1b
                  FROM b
                 WHERE a.col2a = b.col2b)

由于数据量很大,我想定期提交行(比如5000条记录)。 你能建议吗。

3 个答案:

答案 0 :(得分:4)

由于您在问题中显示的查询包含子查询,因此对于正在更新的每一行,这都是在表b上进行查找。这可能很慢,无论如何,更新是一个足够慢的操作。

根据表的设计,我会尝试“更新视图”或MERGE。 UPDATE的能力取决于是否存在“密钥保留连接”。如果你没有,UPDATE将无法正常工作。如果没有表格的DDL,给出正确答案有点困难。

UPDATE (
  select col1a, col1b, col2a, col2b
  from 
    a join b on (a.col2a = b.col2b)
)
set col1a = col1b;

如果UPDATE不起作用,您可以尝试使用MERGE。这应该在更新的情况下工作。

merge into a
using b on (a.col2a = b.col2b)
when matched then update set a.col1a = b.col1b

这两个语句的优点是它们可以处理整个数据集,而不是一次更新一行。要让更新表现良好可能很困难。

如果有col1a列,可能还需要删除任何索引。

答案 1 :(得分:1)

谢谢大家。我得到了解决方案。  我正在寻找下面的解决方案

        CREATE OR REPLACE PROCEDURE xxwv_cc_token_conversion (
   p_source_table   IN   VARCHAR2,
   p_dest_table     IN   VARCHAR2,
   p_column_name    IN   VARCHAR2,
   p_commit_row     IN   NUMBER
)
IS
   TYPE cv_typ IS REF CURSOR;

   t_cur    cv_typ;

   TYPE token_num IS TABLE OF xxwv_ap_token_test2.token_number%TYPE
      INDEX BY BINARY_INTEGER;

   TYPE row_num IS TABLE OF xxwv_ap_token_test2.row_id%TYPE
      INDEX BY BINARY_INTEGER;

   ex_sql   VARCHAR2 (2000);
   t_num    token_num;
   r_num    token_num;
BEGIN
   OPEN t_cur FOR    ' SELECT token_number, row_id FROM '
                  || p_source_table
                  || ' WHERE ROWNUM < 100';

   LOOP
      FETCH t_cur
      BULK COLLECT INTO t_num, r_num LIMIT p_commit_row;

      ex_sql :=
            'UPDATE '
         || p_dest_table
         || ' SET '
         || p_column_name
         || ' = :1,token_flag = ''Y''  WHERE row_id =  :2';
      FORALL i IN 1 .. t_num.COUNT
         EXECUTE IMMEDIATE ex_sql
                     USING t_num (i), r_num (i);
      COMMIT;
      DBMS_OUTPUT.put_line ('commit finished');
      EXIT WHEN t_cur%NOTFOUND;
   END LOOP;

   CLOSE t_cur;

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('Error occured while updating' || SQLERRM);
END xxwv_cc_token_conversion;

答案 2 :(得分:0)

如果您愿意,如果可能,在您的环境中,您可以

 create table newtable as select .... from oldtable

将创建一个新表。

然后重新创建索引,重命名这两个表并重新创建约束。