虽然Oracle提供的DETERMINISTIC声明,本意是确保函数的确定性,但是如何合理利用,是可以用来提高性能的。
这一篇描述ARRAY对性能的影响。
关于DETERMINISTIC函数,以前已经写过一些文章了,不过对于DETERMINISTIC声明用来提高性能只是简单提了一句,并没有展开来说。
由于函数声明了DETERMINISTIC特性,Oracle对于相同的输入,可以只运行一次,而这对于代码比较复杂,调用时间较长的函数而言,确实可以提高性能。
但是在上面的几篇文章中也提到了,DETERMINISTIC是基于调用的,因此使用DETERMINISTIC不但与输入参数是否重复有关,也与SQL调用次数有关。
一个前面文章提到过的简单的例子就是sqlplus的数组方式FETCH数据,不同的array的值,就会影响DETERMINISTIC函数的运行次数,哪怕
不过这里要澄清以前一个错误的观点,由于设置ARRAY为1后,访问DETERMINISTIC函数发现每两条记录调用一次,当时认为ARRAY方式的最小值是2,但是现在发现,问题和ARRAY无关,导致问题的原因和DETERMINISTIC的实现算法有关。
由于DETERMINISTIC并不像RESULT_CACHE那样,在单独的内存区域中保存每次调用的结果,因此Oracle需要判断DETERMINISTIC函数两次输入是否一样,这对于输入参数相同的情况还简单一些,但是对于包含大量变化的变量,就使得函数的调用次数很难预料。
看一个简单的例子来说明这个问题:
SQL> CREATE OR REPLACE FUNCTION F_DETER (V_IN NUMBER)
2 RETURN NUMBER DETERMINISTIC AS
3 BEGIN
4 DBMS_LOCK.SLEEP(1);
5 DBMS_OUTPUT.PUT_LINE(V_IN);
6 RETURN V_IN;
7 END;
8 /
函数已创建。
SQL> CREATE TABLE T_DETER (ID NUMBER, C NUMBER);
表已创建。
SQL> INSERT INTO T_DETER
2 SELECT ROWNUM, 1
3 FROM TAB;
已创建15行。
SQL> SET SERVEROUT ON
SQL> SET TIMING ON
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
会话已更改。
已用时间: 00: 00: 00.09
SQL> SHOW ARRAY
arraysize 15
SQL> SELECT ID, F_DETER(C), SYSDATE FROM T_DETER;
ID F_DETER(C) SYSDATE
---------- ---------- -------------------
1 1 2011-05-26 08:10:54
2 1 2011-05-26 08:10:54
3 1 2011-05-26 08:10:54
4 1 2011-05-26 08:10:54
5 1 2011-05-26 08:10:54
6 1 2011-05-26 08:10:54
7 1 2011-05-26 08:10:54
8 1 2011-05-26 08:10:54
9 1 2011-05-26 08:10:54
10 1 2011-05-26 08:10:54
11 1 2011-05-26 08:10:54
12 1 2011-05-26 08:10:54
13 1 2011-05-26 08:10:54
14 1 2011-05-26 08:10:54
15 1 2011-05-26 08:10:54
已选择15行。
1
1
已用时间: 00: 00: 02.80
SQL> CREATE OR REPLACE FUNCTION F_SYSDATE RETURN DATE AS
2 BEGIN
3 RETURN SYSDATE;
4 END;
5 /
函数已创建。
已用时间: 00: 00: 00.04
SQL> SELECT ID, F_DETER(C), F_SYSDATE FROM T_DETER;
ID F_DETER(C) F_SYSDATE
---------- ---------- -------------------
1 1 2011-05-26 08:11:13
2 1 2011-05-26 08:11:14
3 1 2011-05-26 08:11:14
4 1 2011-05-26 08:11:14
5 1 2011-05-26 08:11:14
6 1 2011-05-26 08:11:14
7 1 2011-05-26 08:11:14
8 1 2011-05-26 08:11:14
9 1 2011-05-26 08:11:14
10 1 2011-05-26 08:11:14
11 1 2011-05-26 08:11:14
12 1 2011-05-26 08:11:14
13 1 2011-05-26 08:11:14
14 1 2011-05-26 08:11:14
15 1 2011-05-26 08:11:14