我正在对包含950万条记录的表(Table_A)进行更新。我已经运行了13个小时,但还没有完成!在如何加快速度方面,有人能指出我正确的方向吗?我可以使用PL / SQL将子选项存储到变量中,如果这样可以使它更快。我是甲骨文新手,非常感谢任何帮助。
update Table_A
set STATUS='DELETED', DESC='REDACTED', NAME=dbms_random.string('A', 20)
where Table_B_ID in (
select ID
from Table_B
where Table_C_ID in (
select ID
from Table_C
where XYZ_ID!=56
)
);
Table_A有950万条记录
Table_B有430,000条记录
Table_C有3050个记录
答案 0 :(得分:1)
尝试使用EXISTS而不是列表来编写两个子查询。它的性能要高得多。
请参阅此处进行讨论:https://asktom.oracle.com/pls/asktom/f?p=100:11:0::NO::P11_QUESTION_ID:442029737684
编辑2015-03-02 这是一个使用exists的(希望是正确的)查询:
UPDATE Table_A A
SET A.STATUS='DELETED', A.DESC='REDACTED', A.NAME=dbms_random.string('A', 20)
WHERE EXISTS (
SELECT 1
FROM Table_B B
WHERE A.Table_B_ID = B.ID
AND EXISTS(
SELECT 1
FROM Table_C C
WHERE C.XYZ_ID!=56
AND B.Table_C_ID = C.ID
)
);
答案 1 :(得分:0)
首先在table_b上为Table_C_ID创建索引,
然后创建3个表的统计信息,
dbms_stats.gather_table_stats('OWNER', 'TABLE_A');
dbms_stats.gather_table_stats('OWNER', 'TABLE_B');
dbms_stats.gather_table_stats('OWNER', 'TABLE_C');
之后使用paralell提示:
update /*+parallel(8)*/Table_A
set STATUS='DELETED', DESC='REDACTED', NAME=dbms_random.string('A', 20)
where Table_B_ID in (
select ID
from Table_B
where Table_C_ID in (
select ID
from Table_C
where XYZ_ID!=56
)
);
那些会更好地提高速度
答案 2 :(得分:0)
相应的select
多长时间?
select a.*
from Table_A
where Table_B_ID in (select ID
from Table_B
where Table_C_ID in (select ID
from Table_C
where XYZ_ID <> 56
)
);
据推测,这并不快,我的猜测是由于缺乏索引而不快。对于此查询,我建议使用以下复合索引:table_b(Table_C_ID, ID)
和table_c(xyz_id, id)
。我建议您在使用select
之前让update
快速工作。
请注意,这只是猜测。例如,您可以更新Table_A
中的每一行,这是一个真正的性能值。或者,一个或多个表上可能存在锁定导致数据争用。
答案 3 :(得分:0)
感谢大家的建议。我一次尝试一次。
在所有情况下,显然使用exists
与in
不同。例如,如果我将in
替换为exists
:
update Table_A
set STATUS='DELETED', DESC='REDACTED', NAME=dbms_random.string('A', 20)
where exists (
select ID
from Table_B
where exists (
select ID
from Table_C
where XYZ_ID!=56
)
);