我在Oracle中有两个大表(每个表约4000万行)。 我需要基于单个联接使用tableB中的数据更新tableA。 我尝试过:
update tableA a
set (a.column2)=
(select b.column2 from tableB b
where a.column1=b.column1)
它可以工作,但是大约需要1个小时才能完成。
我还检查了以下内容(解释计划):
merge into tableA a
using (select b.column1, b.column2 from tableB b) b
on (a.column1=b.column1)
when matched then
update set a.column2=b.column2
但是它的成本似乎是第一个查询的10倍。 我也尝试使用游标进行更新,但花了2个小时才完成。
两个表的索引都在column1上。 TableA还按月划分分区。
任何想法如何以更有效的方式完成此过程?
谢谢!
答案 0 :(得分:2)
我会尝试在第一个查询中添加where
子句:
update tableA a
set a.column2 = (select b.column2 from tableB b
where a.column1 = b.column1)
where a.column2 <> (select b.column2 from tableB b
where a.column1 = b.column1);
(假设目标值不是NULL
。)
答案 1 :(得分:2)
您是否尝试过以下方法?
UPDATE
(SELECT tableA.column2 as OLD, tableB.column2 as NEW
FROM tableA
INNER JOIN tableB
ON tableA.column1 = tableB.column1
) t
SET t.old = t.new
答案 2 :(得分:1)
对于批量插入或更新,我将永远在oracle中使用。 以下代码可能会有一些错误,但是您可以将其更正并用于批量处理
declare
c_limit number:10000;
CURSOR c_update IS
SELECT b.column1,b.column2 from tableB b,tableA a where a.column1=b.column1
type upd_Arry is table of c_update%rowtype;
upd_val upd_Arry;
BEGIN
OPEN c_update;
LOOP
FETCH c_update BULK COLLECT INTO upd_val LIMIT c_limit;
FORALL i IN 1..l_data.COUNT
update tableA
set column2=upd_val(i).b.column2
where column1=upd_val(i).b.column1;
EXIT WHEN c_update%NOTFOUND;
END LOOP;
commit;
CLOSE c_update;
END ;