SQL更新大table

SQL Update large table

我有一个问题。我需要更新两个大的 table - t_contact(1.7 亿行)和 t_participants(1100 万行)。这 table 都有列 CUSTOMER_ID。其中一些 ID 错误,我需要更新它。错误的ID大约是14万。 我明白如果我会使用UPDATE TABLE需要很多次,但是这两个table肯定不能长时间不可用。我该怎么办?

将您的一张表拆分成多个部分,然后在 PL/SQL 块中一个一个地处理它们。例如,假设 ID 是后继的,您将 t_participants 分成几部分,每部分有 100 万行:

begin
  -- 1 and 11 - hardcoded values, 
  -- since your t_participants table has 11 000 000 rows
  for i in 1..11 loop 
    merge t_contact c
    using (select * from t_participants 
           where id between (i - 1) * 1000000 and i * 1000000) p
       on (c.id = p.id)
     when matched then update ...;
  commit;
  end loop;
end;

我取了1000000条记录的一部分的大小,但你可以选择其他大小。这将取决于您的服务器性能。尝试手动更新 100、1000、10000 等行以定义最方便的大小。

如果您在应该使用合并的地方存储了错误的 ID:

MERGE INTO t_contact D
USING (select * from t_wrong_ids) S
ON (D.CUSTOMER_ID = S.NEW_ID)
WHEN MATCHED THEN UPDATE SET D.CUSTOMER_ID = S.OLD_ID

比正常更新快很多。

第二个table是一样的:

MERGE INTO t_participants D
USING (select * from t_wrong_ids) S
ON (D.CUSTOMER_ID = S.NEW_ID)
WHEN MATCHED THEN UPDATE SET D.CUSTOMER_ID = S.OLD_ID
declare
  i number := 0;
  cursor s1 is SELECT rowid, t.* FROM table_name  t WHERE column_name =x;
begin
  for c1 in s1 loop
      UPDATE table_name SET column_name = y
             where rowid = c1.rowid;
      i := i + 1;              -- Commit after every X records
      if i > 50000 then
         commit;
         i := 0;
      end if;
  end loop;
  commit;
end;
/