我通过获取addr_id并在两个表(同一个表和另一个表)中为不同的列更新它来执行地址关联。然而,即使我使用平行度为500的平行提示,也需要花费大量时间。你能在这里帮忙吗?下面是程序。
PROCEDURE
ADD_ASOC AS
BEGIN
DECLARE
CURSOR C1 IS
SELECT /*+ PARALLEL(500) */ ADDR_ID FROM TEMP_ADDR WHERE BATCH_RANGE BETWEEN 100 AND 900;
TYPE CURSOR_ATT IS TABLE OF C1%ROWTYPE;
L_CURSOR CURSOR_ATT;
BEGIN
OPEN C1;
LOOP
FETCH C1 BULK COLLECT INTO L_CURSOR LIMIT 5000;
EXIT WHEN L_CURSOR.COUNT = 0;
FOR I IN 1 .. L_CURSOR.COUNT LOOP
UPDATE /*+ PARALLEL(500) */ MAIN_ADDR SET ADR_NAME = L_CURSOR(I).ADDR_ID||'RESIDENCE'
WHERE ADDR_ID = L_CURSOR(I).ADDR_ID;
UPDATE /*+ PARALLEL(500) */ TEMP_ADDR SET ADR_NAME = L_CURSOR(I).ADDR_ID||'RESIDENCE'
WHERE ADDR_ID = L_CURSOR(I).ADDR_ID
AND BATCH_RANGE BETWEEN 100 AND 900;
COMMIT;
END LOOP;
END LOOP;
COMMIT;
CLOSE C1;
END;
COMMIT;
字符串
我使用平行度为500执行,但无效。
2条答案
按热度按时间jaql4c8m1#
您似乎不需要游标或循环,并且可以使用
MERGE
语句和UPDATE
语句字符串
COMMIT
,那么您不能使用多个过程,然后如果最后一个失败,请选择ROLLBACK
全部。相反,您应该从过程中删除COMMIT
,并从调用过程的会话中调用COMMIT
,然后您将能够将多个过程链接在一起。(另外,重复使用COMMIT
非常慢。slhcrj9b2#
update
语句上的parallel
提示充其量是无意义的。commit
非常昂贵。在循环的每一次迭代上执行commit
将非常慢。forall
比执行for
循环更高效。在单个SQL语句中执行更新是最有效的方法。select
语句的并行度为500的?这似乎是非常非常不可能的,这是一个合理的数字。除此之外,你做了什么来跟踪你的代码,或者看看是什么花了时间。我们当然可以猜测可能会很慢的事情,但是我们没有办法看到,例如,你的一个表是否缺少
addr_id
上的索引,或者是否有一堆未索引的外键需要管理,或者是否有触发器使事情变慢。forall
方法会更快(不如单个update
语句快,但比循环中的逐行处理更好)。字符串
UPDATE /+ PARALLEL(500)/ TEMP_ADDR SET ADR_NAME = L_CURSOR(I).ADDR_ID||“住宅”
其中ADDR_ID = L_CURSOR(I).ADDR_ID和BATCH_RANGE在100和900之间;