我有一个表AA包含6列(a
,b
,c
,d
,e
,f
),有a
,b
,c
作为复合键的2亿条记录。列a
,列b
或列c
可能包含多个重复条目。列c
包含多个条目,每个a
和b
。
我必须复制列a
,b
,d
,e
,f
(c
不存在的值的值转入另一个表AB,其中列a
,b
,d
,e
,f
与a
,b
,{ {1}}作为复合键,以便列d
的最大值为2且d
,a
,b
的最大值为2。
我写了一个程序:
d
在Toad中以CREATE OR REPLACE Table_CHANGES(d IN AB.d%TYPE)
AS
aaa AB.a%TYPE;
aab AB.b%TYPE;
i NUMBER := 0;
countRow NUMBER;
CURSOR distinctUserIdCursor IS
SELECT DISTINCT urt.a, urt.b FROM AA urt WHERE urt.d = aad ORDER BY urt.a;
BEGIN
OPEN distinctUserIdCursor;
LOOP
FETCH distinctUserIdCursor INTO aaa, aab;
EXIT WHEN distinctUserIdCursor%NOTFOUND;
SELECT COUNT(*) INTO countRow FROM AB ur
WHERE ur.a = aaa
AND ur.b = aab
AND ur.d = aad;
IF (countRow > 0) THEN
DBMS_OUTPUT.PUT_LINE('Entry exist in AB');
ELSE
INSERT INTO AB
SELECT urt.a, urt.b, urt.d, urt.e,
urt.f FROM AA urt
WHERE urt.a = aaa
AND urt.d = aad
AND urt.b = aab
AND ROWNUM = 1;
i := i+1;
END IF;
IF (i = 1000) THEN
COMMIT;
i := 0;
END IF;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error in Insertion of new role'
|| '~~~~' || SQLERRM);
CLOSE distinctUserIdCursor;
END;
/
和exec Table_CHANGES('value1')
执行此过程时,大约需要40分钟并继续执行toad。很难知道如果toad实际上正在执行任务或进入睡眠状态。
我可以优化此程序,以便在表AB中插入数千万个数据所需的时间更短吗?
答案 0 :(得分:0)
我厌倦了使用收藏品来实现你正在做的事情。请查看这些是否符合您的要求并提高性能。
create table AA(a number, b number,c number,d number, e number,f number );
create table AB(a number, b number,d number, e number,f number );
步骤:
CREATE OR REPLACE procedure Table_CHANGES(aad IN AB.d%TYPE)
AS
-- aaa AB.a%TYPE;
-- aab AB.b%TYPE;
-- i NUMBER := 0;
-- countRow NUMBER;
///**Put some filtering logic here like i have put a minus ***///
CURSOR distinctUserIdCursor(aad number) IS
SELECT DISTINCT urt.a,
urt.b,
urt.d,
urt.e,
urt.f
FROM AA urt
WHERE urt.d = aad
minus
SELECT DISTINCT ur.a,
ur.b,
ur.d,
ur.e,
ur.f
FROM AB ur
WHERE ur.d = aad;
type var_cur is table of distinctUserIdCursor%rowtype;
var var_cur;
BEGIN
OPEN distinctUserIdCursor(aad);
LOOP
FETCH distinctUserIdCursor bulk collect into var limit 100;
EXIT WHEN distinctUserIdCursor%NOTFOUND;
FORALL i IN 1 .. var.count SAVE EXCEPTIONS
INSERT INTO AB
VALUES var(i);
END LOOP;
CLOSE distinctUserIdCursor;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error in Insertion of new role' || '~~~~' || SQLERRM);
FOR indx IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
LOOP
DBMS_OUTPUT.put_line (SQL%BULK_EXCEPTIONS (indx).ERROR_INDEX|| ': '
|| SQL%BULK_EXCEPTIONS (indx).ERROR_CODE);
END LOOP;
END;
/
执行:
execute Table_CHANGES(3)