Create Driver for Test
CREATE OR REPLACE PROCEDURE test_cursor_performance (approach IN VARCHAR2)
IS
CURSOR cur
IS
SELECT *
FROM dual
CONNECT BY LEVEL < 100001;
one_row cur%ROWTYPE;
TYPE t IS TABLE OF cur%ROWTYPE
INDEX BY PLS_INTEGER;
many_rows t;
last_timing TIMESTAMP;
cntr number := 0;
PROCEDURE start_timer
IS
BEGIN
last_timing := SYSTIMESTAMP;
END;
PROCEDURE show_elapsed_time (message_in IN VARCHAR2 := NULL)
IS
BEGIN
DBMS_OUTPUT.put_line (
CASE
WHEN message_in IS NULL THEN 'Completed in:'
ELSE '"' || message_in || '" completed in: '
END
|| REGEXP_SUBSTR (SYSTIMESTAMP - last_timing,
'([1-9][0-9:]*|0)\.\d{3}')
|| ' seconds');
END;
BEGIN
start_timer;
CASE approach
WHEN 'implicit cursor for loop'
THEN
FOR j IN cur
LOOP
cntr := cntr + 1;
END LOOP;
DBMS_OUTPUT.put_line (cntr);
WHEN 'explicit open, fetch, close'
THEN
OPEN cur;
LOOP
FETCH cur INTO one_row;
EXIT WHEN cur%NOTFOUND;
cntr := cntr + 1;
END LOOP;
DBMS_OUTPUT.put_line (cntr);
CLOSE cur;
WHEN 'bulk fetch'
THEN
OPEN cur;
LOOP
FETCH cur BULK COLLECT INTO many_rows LIMIT 100;
EXIT WHEN many_rows.COUNT () = 0;
FOR indx IN 1 .. many_rows.COUNT
loop
cntr := cntr + 1;
end loop;
END LOOP;
DBMS_OUTPUT.put_line (cntr);
CLOSE cur;
END CASE;
show_elapsed_time (approach);
END test_cursor_performance;
Procedure created.
Turn off Optimization of PL/SQL Code
ALTER PROCEDURE test_cursor_performance COMPILE plsql_optimize_level=0
Procedure altered.
Without Optimization
BEGIN
DBMS_OUTPUT.put_line ('No optimization...');
test_cursor_performance ('implicit cursor for loop');
test_cursor_performance ('explicit open, fetch, close');
test_cursor_performance ('bulk fetch');
END;
No optimization...
100000
"implicit cursor for loop" completed in: 1.215 seconds
100000
"explicit open, fetch, close" completed in: 1.187 seconds
100000
"bulk fetch" completed in: 0.070 seconds
Set Optimization to Default Level
ALTER PROCEDURE test_cursor_performance COMPILE plsql_optimize_level=2
Procedure altered.
Now with Optimization
BEGIN
DBMS_OUTPUT.put_line ('Default optimization...');
test_cursor_performance ('implicit cursor for loop');
test_cursor_performance ('explicit open, fetch, close');
test_cursor_performance ('bulk fetch');
END;
Default optimization...
100000
"implicit cursor for loop" completed in: 0.075 seconds
100000
"explicit open, fetch, close" completed in: 1.164 seconds
100000
"bulk fetch" completed in: 0.071 seconds
Now with Debug (Reduced Optimization)
ALTER PROCEDURE test_cursor_performance COMPILE DEBUG
Procedure altered.
BEGIN
DBMS_OUTPUT.put_line ('DEBUG enabled...');
test_cursor_performance ('implicit cursor for loop');
test_cursor_performance ('explicit open, fetch, close');
test_cursor_performance ('bulk fetch');
END;
DEBUG enabled...
100000
"implicit cursor for loop" completed in: 1.153 seconds
100000
"explicit open, fetch, close" completed in: 1.163 seconds
100000
"bulk fetch" completed in: 0.070 seconds