Homegrown Sleep Procedure
CREATE OR REPLACE PROCEDURE pause_program (secs_in IN PLS_INTEGER) AUTHID DEFINER
IS
c_secs_in_day CONSTANT PLS_INTEGER := 24 * 60 * 60;
l_date DATE := SYSDATE;
l_diff NUMBER;
BEGIN
LOOP
l_diff := SYSDATE - l_date;
EXIT WHEN l_diff > (secs_in / c_secs_in_day);
END LOOP;
END;
Procedure created.
A Pure Function
CREATE OR REPLACE FUNCTION betwnstr (
string_in IN VARCHAR2
, start_in IN INTEGER
, end_in IN INTEGER
)
RETURN VARCHAR2
IS
BEGIN
pause_program (1);
RETURN (SUBSTR (string_in, start_in, end_in - start_in + 1));
END;
Function created.
Run It Five Times
DECLARE
l_start PLS_INTEGER;
BEGIN
l_start := DBMS_UTILITY.get_time;
FOR rec IN (SELECT betwnstr ('FEUERSTEIN', 1, 5)
FROM hr.employees
WHERE ROWNUM <= 5)
LOOP
NULL;
END LOOP;
DBMS_OUTPUT.put_line ( 'Non-deterministic in query elapsed: '
|| TO_CHAR (DBMS_UTILITY.get_time - l_start)
);
END;
Non-deterministic in query elapsed: 979
Add the DETERMINISTIC Keyword
CREATE OR REPLACE FUNCTION betwnstr (
string_in IN VARCHAR2
, start_in IN INTEGER
, end_in IN INTEGER
)
RETURN VARCHAR2 DETERMINISTIC
IS
BEGIN
pause_program (1);
RETURN (SUBSTR (string_in, start_in, end_in - start_in + 1));
END;
Function created.
Now Much Faster
DECLARE
l_start PLS_INTEGER;
BEGIN
l_start := DBMS_UTILITY.get_time;
FOR rec IN (SELECT betwnstr ('FEUERSTEIN', 1, 5)
FROM hr.employees
WHERE ROWNUM <= 5)
LOOP
NULL;
END LOOP;
DBMS_OUTPUT.put_line ( 'Deterministic in query lapsed: '
|| TO_CHAR (DBMS_UTILITY.get_time - l_start)
);
END;
Deterministic in query lapsed: 197
Back to the Slow Version
DECLARE
l_string VARCHAR2 (100);
l_start PLS_INTEGER;
BEGIN
l_start := DBMS_UTILITY.get_time;
FOR rec IN (SELECT *
FROM hr.employees
WHERE ROWNUM <= 5)
LOOP
SELECT betwnstr ('FEUERSTEIN', 1, 5)
INTO l_string
FROM DUAL;
END LOOP;
DBMS_OUTPUT.put_line ( 'Deterministic in SELECT from DUAL elapsed: '
|| TO_CHAR (DBMS_UTILITY.get_time - l_start)
);
END;
Deterministic in SELECT from DUAL elapsed: 998