关于oracle 函数的Deterministic

在建立函数索引的时候,自定义的函数需要加Deterministic

确定性函数的性能好处是如果使用相同的输入调用函数两次,Oracle可以记住第一个调用的结果因此避免在第二次执行时再次调用。

但是该功能直到10g Release 2才被真正实施。

环境11g

测试1:

create or replace package deter_body is

  v_glo_count pls_integer:=0;

end deter_body; --可以定义全局变量,这里先不用,还要归零操作,麻烦


 create or replace function deter_fun(num pls_integer)

 return  pls_integer

 as   

 begin

   dbms_output.put_line('访问flag');

   return num;

 end deter_fun;

             

--观察输出结果

--这种调用,每一行都会访问一次, 因为操作的是筛选后的行值

select deter_fun(5)  from emp e where e.deptno=20;

--发现deter_fun的调用次数为emp的记录数,可怕,相当于,先全表调一次函数,再使用条件

select * from emp e where e.deptno= deter_fun(20);                                       

 

--加Deterministic

create or replace function deter_fun(num pls_integer)

 return  pls_integer  Deterministic

 as   

 begin

   dbms_output.put_line('访问flag');

   return num;

 end deter_fun;

 

--可以看到

--访问一次

select deter_fun(5)  from emp e where e.deptno=20;

--访问一次

select * from emp e where e.deptno= deter_fun(20);

        

--4

select  deter_fun(level) from dual connect by rownum<5;

例2:

create or replace function deter_fun2

 return   pls_integer

 as

   v_val number;

 begin

   v_val:=trunc(dbms_random.value(0,999)); 

   dbms_output.put_line('访问flag');

   return v_val;       

  

 end deter_fun2;

--访问14

select * from emp e where e.empno=deter_fun2();

 

 

--我们加上Deterministic看看

create or replace function deter_fun2

 return   pls_integer Deterministic

 as

   v_val number;

 begin

   v_val:=trunc(dbms_random.value(0,999)); 

   dbms_output.put_line('访问flag');

   return v_val;       

  

 end deter_fun2;

        

 --只访问一次

 select * from emp e where e.empno=deter_fun2();

通过执行计划的递归调用次数也可以看出来,大家可以验证

猜你喜欢

转载自blog.csdn.net/u011165335/article/details/80160760