虽然Oracle提供的DETERMINISTIC声明,本意是确保函数的确定性,但是如何合理利用,是可以用来提高性能的。
这一篇描述参数顺序对性能的影响。
上一篇文章提到了,如果希望通过DETERMINISTIC来获取性能收益,那么采用批量方式是必须的,而且数组的值相对而言越大对于性能的帮助会越大。
但是这里存在一个问题,如果需要处理的数据量本身很大,虽然重复的输入参数不少,但是总的参数不同的值更多,那么即使将ARRAY的值设置到1000,能带来的性能收益也很有限,因为即使1000次调用,也不能保证参数完全一样出现多次,而如果无限制的增大ARRAY,虽然从DETERMINISTIC函数的角度讲可以提高性能,但是对于内存的占用等其他方面,会带来性能的下降,显然一味的扩大批量并不是问题的解决之道。
其实解决这个问题很简单,就是在调用DETERMINISTIC函数之前,对函数的参数进行排序,确保相同的参数顺序调用,这样DETERMINISTIC函数执行的次数最少。
继续使用上一篇文章的例子,看看排序后DETERMINISTIC函数的调用次数:
SQL> UPDATE T_DETER SET C = 1;
已更新15行。
已用时间: 00: 00: 00.17
SQL> SELECT ID, F_DETER(C), F_SYSDATE FROM T_DETER;
ID F_DETER(C) F_SYSDATE
---------- ---------- -------------------
1 1 2011-05-26 14:26:12
2 1 2011-05-26 14:26:13
3 1 2011-05-26 14:26:13
4 1 2011-05-26 14:26:13
5 1 2011-05-26 14:26:13
6 1 2011-05-26 14:26:13
7 1 2011-05-26 14:26:13
8 1 2011-05-26 14:26:13
9 1 2011-05-26 14:26:13
10 1 2011-05-26 14:26:13
11 1 2011-05-26 14:26:13
12 1 2011-05-26 14:26:13
13 1 2011-05-26 14:26:13
14 1 2011-05-26 14:26:13
15 1 2011-05-26 14:26:13
已选择15行。
1
1
已用时间: 00: 00: 02.29
SQL> SELECT ID, F_DETER(C), F_SYSDATE FROM (SELECT * FROM T_DETER ORDER BY C);
ID F_DETER(C) F_SYSDATE
---------- ---------- -------------------
1 1 2011-05-26 14:26:35
15 1 2011-05-26 14:26:35
3 1 2011-05-26 14:26:35
4 1 2011-05-26 14:26:35
5 1 2011-05-26 14:26:35
6 1 2011-05-26 14:26:35
7 1 2011-05-26 14:26:35
8 1 2011-05-26 14:26:35
9 1 2011-05-26 14:26:35
10 1 2011-05-26 14:26:35
11 1 2011-05-26 14:26:35
12 1 2011-05-26 14:26:35
13 1 2011-05-26 14:26:35
14 1 2011-05-26 14:26:35
2 1 2011-05-26 14:26:35
已选择15行。
1
已用时间: 00: 00: 01.10
可以看到,由于执行了排序,DETERMINISTIC函数不用再次检查输入参数是否相等,因此在SQL运行期间只调用了一次:
SQL> SHOW ARRAY
arraysize 15
SQL> SET ARRAY 1
SQL> SELECT ID, F_DETER(C), F_SYSDATE FROM (SELECT * FROM T_DETER ORDER BY C);
ID F_DETER(C) F_SYSDATE
返回栏目页:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/