Thursday 4 January 2007

Re-writing an Update for Massive Performance Gain

Had the following update on a table with more than 5 million records, which was taking forever:

DECLARE

CURSOR c1 IS
SELECT DISTINCT substr(rowid,1,13)
FROM f_adversereaction;


TYPE RowIdType IS TABLE OF VARCHAR2(18) INDEX BY BINARY_INTEGER;
p_rowid RowIdType;

TYPE p_idType IS TABLE OF f_adversereaction.adversereactionid%TYPE INDEX BY BINARY_INTEGER;
p_id p_idType;

BEGIN


OPEN c1;
FETCH c1 BULK COLLECT INTO p_rowid;

FORALL indx IN p_rowid.FIRST..p_rowid.LAST
UPDATE f_adversereaction A
SET a.originalsenderid = (
SELECT F.ORiginalsenderid
FROM f_safetyreport F
WHERE a.safetyreportid = f.safetyreportid )
WHERE a.ROWID LIKE p_rowid(indx)||'%';
END;

Rewrote like this, and update was done in minutes:

DECLARE

CURSOR c1 IS
SELECT a.adversereactionid,F.ORiginalsenderid
FROM f_safetyreport F
,f_adversereaction A
WHERE a.safetyreportid = f.safetyreportid;

TYPE p_idType IS TABLE OF f_adversereaction.adversereactionid%TYPE INDEX BY BINARY_INTEGER;
p_id p_idType;

TYPE p_SenderType IS TABLE OF f_adversereaction.originalsenderid%TYPE INDEX BY BINARY_INTEGER;
p_sender p_senderType;

BEGIN

OPEN c1;
FETCH c1 BULK COLLECT INTO p_id,p_sender;

FORALL indx IN p_id.FIRST..p_id.LAST
UPDATE f_adversereaction A
SET a.originalsenderid = p_sender(indx)
WHERE a.adversereactionid = p_id(indx);

COMMIT;

END;

No comments: