I have a situation where I need to delete the data from Log table from my Oracle Database. The table contains around 3159037 rows with CLOB content, now as a maintenance activity I need to purge old data by keeping last 6 months from current date. I have designed the PL/SQL program to achieve this however during my test I found that even for deleting 1000 records, the procedure is taking around 22 seconds to complete its execution. Now lets assume we have more than 100000+ records to delete it will take huge amount of time to complete its execution.
Can anyone suggest the better way to approach this problem.
Below is my current script with FORALL and BULK COLLECT functionality to get performance benefit.
CREATE OR replace PROCEDURE Integration_data_purge
authid current_user
AS
c_limit CONSTANT PLS_INTEGER DEFAULT 100;
CURSOR int_cur IS
SELECT a.ROWID AS a_rowid,
b.ROWID AS b_rowid
FROM integration_log a,
integration_errors b
WHERE a.error_log_id = b.error_rec_id(+)
AND Trunc(a.insert_date) < Trunc(SYSDATE) - 180;
TYPE int_aat
IS TABLE OF int_cur%ROWTYPE INDEX BY PLS_INTEGER;
l_integration_log INT_AAT;
--l_count INTEGER := 1;
start_time NUMBER;
end_time NUMBER;
BEGIN
start_time := dbms_utility.get_time;
OPEN int_cur;
LOOP
FETCH int_cur bulk collect INTO l_integration_log limit c_limit;
--DBMS_OUTPUT.put_line ('Retrieved in RUN '|| l_count ||' = ' ||
-- l_integration_log.COUNT);
EXIT WHEN l_integration_log.count = 0;
--if l_integration_log.count <> 0 then
forall indx IN 1 .. l_integration_log.count
DELETE FROM integration_log
WHERE ROWID = L_integration_log(indx).a_rowid;
--DBMS_OUTPUT.put_line ('Total rows deleted from INTEGRATION_LOG = ' ||
--SQL%ROWCOUNT);
forall indx IN 1 .. l_integration_log.count
DELETE FROM integration_errors
WHERE ROWID = L_integration_log(indx).b_rowid;
--DBMS_OUTPUT.put_line ('Total rows deleted from INTEGRATION_ERRORS = ' ||
--SQL%ROWCOUNT);
--l_count := l_count + 1;
--end if;
--commit;
END LOOP;
CLOSE int_cur;
end_time := dbms_utility.get_time;
dbms_output.Put_line('Execution Completed : '
|| To_char(( end_time - start_time ) / 100)
|| ' Seconds');
END;
integration_errors
has a foreign key to tableintegration_log
and you addedON DELETE CASCADE
when you defined the foreign key, then deleting a row fromintegration_log
will also delete all related rows in tableintegration_errors
. – Abra