10

在 SQLSELECT语句中,我想执行一个对该SELECT语句范围具有确定性的函数(或者事务也可以):

select t.x, t.y, my_function(t.x) from t

的许多值t.x是相同的,因此 Oracle 可以省略一次又一次地调用相同的函数,以加快处理速度。但是,如果我将函数标记为DETERMINISTIC,则结果可能会在此查询的多次执行之间缓存。我不能使用的原因DETERMINISTIC是因为my_function使用了一个不时更改的配置参数。

我可以使用其他关键字吗?是否有任何我应该注意的问题(内存问题、并发性等)?或者可能有任何其他技巧,例如每个t.x值只调用一次函数的分析函数(不会对性能产生重大影响)?

4

4 回答 4

11

如果你这样做:

select t.x, t.y, (select my_function(t.x) from dual)
from t

那么Oracle可以使用子查询缓存来实现减少函数调用。

于 2011-09-01T13:20:32.413 回答
3

这不是您问题的答案,但可以为您提供解决方案。你提到的这个配置参数,不能作为参数添加到函数中吗?在这种情况下,my_function(t.x, val1)my_function(t.x, val2).

于 2011-09-01T13:09:06.180 回答
2

一个可能的简单解决方法是创建第二个 DETERMINISTIC 函数,该函数调用第一个函数;但是让第二个函数采用一个额外的、无意义的参数,您可以在使用该函数的每个查询中为其提供不同的文字值。

于 2011-09-01T13:07:22.967 回答
2

另一种方法是将函数放在一个包中,并将结果设置为全局变量。然后在调用该函数时检查输入变量是否与之前相同,如果是则快速返回全局变量:

SQL> create or replace package temp is
  2
  3    function blah ( PIndex integer ) return integer;
  4
  5  end temp;
  6  /

Package created.

SQL>
SQL> create or replace package body temp is
  2
  3    GResult integer := 0;
  4    GIndex integer;
  5
  6    function blah ( PIndex integer ) return integer is
  7
  8      begin
  9
 10        if Gindex = Pindex then
 11          return Gresult;
 12        else
 13          GIndex := Pindex;
 14          GResult := Pindex;
 15        end if;
 16
 17        return Gresult;
 18
 19      end blah;
 20
 21  end temp;
 22  /

Package body created.

SQL>
SQL> select temp.blah(1) from dual;

TEMP.BLAH(1)
------------
           1

SQL>
SQL> select temp.blah(1) from dual;

TEMP.BLAH(1)
------------
           1

SQL>
SQL> select temp.blah(2) from dual;

TEMP.BLAH(2)
------------
           2

SQL>
于 2011-09-01T13:32:17.697 回答