Package to Calculate Elapsed Time
CREATE OR REPLACE PACKAGE tmr
IS
PROCEDURE start_timer;
PROCEDURE show_elapsed_time (message_in IN VARCHAR2 := NULL);
END tmr;
Package created.
CREATE OR REPLACE PACKAGE BODY tmr
IS
last_timing NUMBER := NULL;
PROCEDURE start_timer
IS
BEGIN
last_timing := DBMS_UTILITY.get_time;
END;
PROCEDURE show_elapsed_time (message_in IN VARCHAR2 := NULL)
IS
BEGIN
DBMS_OUTPUT.put_line (
message_in
|| ': '
|| MOD (DBMS_UTILITY.get_time - last_timing + POWER (2, 32),
POWER (2, 32)));
start_timer;
END;
END tmr;
Package Body created.
CREATE TABLE explimpl_data
(
n INTEGER PRIMARY KEY
, name VARCHAR2 (100)
)
Table created.
Load up the table!
BEGIN
FOR indx IN 1 .. 100000
LOOP
INSERT INTO explimpl_data
VALUES (indx, 'My name is ' || indx);
END LOOP;
COMMIT;
END;
1 row(s) inserted.
Test Package: Both Explicit and Implicit Pathways
CREATE OR REPLACE PACKAGE explimpl
AS
FUNCTION explicit (n_in IN explimpl_data.n%TYPE)
RETURN explimpl_data%ROWTYPE;
FUNCTION implicit (n_in IN explimpl_data.n%TYPE)
RETURN explimpl_data%ROWTYPE;
FUNCTION explicit_with_conversion (n_in IN explimpl_data.n%TYPE)
RETURN explimpl_data%ROWTYPE;
END explimpl;
Package created.
CREATE OR REPLACE PACKAGE BODY explimpl
IS
FUNCTION implicit (n_in IN explimpl_data.n%TYPE)
RETURN explimpl_data%ROWTYPE
IS
onerow_rec explimpl_data%ROWTYPE;
BEGIN
SELECT *
INTO onerow_rec
FROM explimpl_data
WHERE n = n_in;
RETURN onerow_rec;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN onerow_rec;
END implicit;
FUNCTION explicit (n_in IN explimpl_data.n%TYPE)
RETURN explimpl_data%ROWTYPE
IS
CURSOR onerow_cur
IS
SELECT *
FROM explimpl_data
WHERE n = n_in;
onerow_rec explimpl_data%ROWTYPE;
BEGIN
OPEN onerow_cur;
FETCH onerow_cur INTO onerow_rec;
CLOSE onerow_cur;
RETURN onerow_rec;
END explicit;
FUNCTION explicit_with_conversion (n_in IN explimpl_data.n%TYPE)
RETURN explimpl_data%ROWTYPE
IS
CURSOR onerow_cur
IS
SELECT *
FROM explimpl_data
WHERE n = TO_CHAR (n_in);
onerow_rec explimpl_data%ROWTYPE;
BEGIN
OPEN onerow_cur;
FETCH onerow_cur INTO onerow_rec;
CLOSE onerow_cur;
RETURN onerow_rec;
END explicit_with_conversion;
END explimpl;
Package Body created.
Performance Comparison Driver
CREATE OR REPLACE PROCEDURE compare_explimpl (
title_in IN VARCHAR2
, counter_in IN INTEGER
, n_in IN explimpl_data.n%TYPE := 138
)
IS
emprec explimpl_data%ROWTYPE;
BEGIN
DBMS_OUTPUT.put_line ('Compare Explicit and Implicit: ');
DBMS_OUTPUT.put_line (title_in);
DBMS_OUTPUT.
put_line ('Iterations and Primary Key: ' || counter_in || '-' || n_in);
tmr.start_timer;
FOR i IN 1 .. counter_in
LOOP
emprec := explimpl.implicit (n_in);
END LOOP;
tmr.show_elapsed_time ('Implicit');
--
tmr.start_timer;
FOR i IN 1 .. counter_in
LOOP
emprec := explimpl.explicit (n_in);
END LOOP;
tmr.show_elapsed_time ('Explicit');
--
tmr.start_timer;
FOR i IN 1 .. counter_in
LOOP
emprec := explimpl.explicit_with_conversion (n_in);
END LOOP;
tmr.show_elapsed_time ('Explicit with datatype conversion');
DBMS_OUTPUT.put_line ('....');
END compare_explimpl;
Procedure created.
Run the Comparison
BEGIN
compare_explimpl ('Successful lookup', 10000, 138);
compare_explimpl ('Unsuccessful lookup', 10000, 138980);
compare_explimpl ('Lookup NULL', 10000, NULL);
END;
Compare Explicit and Implicit:
Successful lookup
Iterations and Primary Key: 10000-138
Implicit: 33
Explicit: 36
Explicit with datatype conversion: 37
....
Compare Explicit and Implicit:
Unsuccessful lookup
Iterations and Primary Key: 10000-138980
Implicit: 51
Explicit: 42
Explicit with datatype conversion: 45
....
Compare Explicit and Implicit:
Lookup NULL
Iterations and Primary Key: 10000-
Implicit: 48
Explicit: 40
Explicit with datatype conversion: 41
....