在第一个示例中,它将仅执行100次。您可以通过在函数中添加调试调用来验证这一点:
create table mytable (a, b) as select mod(level, 10), level from dual connect by level <= 50;create or replace function myfunction(p number)return number asbegin dbms_output.put_line('In function for p=' || p); return mod(p,3);end;/set serveroutput onselect myfunction(b)from mytablewhere a = 1;MYFUNCTION(B)------------- 1 2 0 1 2In function for p=1In function for p=11In function for p=21In function for p=31In function for p=41仅针对与
where子句筛选器匹配的行调用该函数。但是,据我所知,这并不能保证。
在第二个示例中,它要复杂得多,并且在很大程度上取决于优化程序。在我的简单演示中,优化器(在本例中为11gR2)首先进行评估
a,并且仅针对与之匹配的行调用该函数;但随后会再次为select-
list值调用它:
select myfunction(b)from mytablewhere a = 1and myfunction(b) = 2;MYFUNCTION(B)------------- 2 2In function for p=1In function for p=11In function for p=11In function for p=21In function for p=31In function for p=41In function for p=41
a=1与以前一样,对五行中的每一行调用该函数,对于
myfunction(b) = 2第二次被调用的函数,则调用该函数以获取结果集中的值。
同样,对于此示例,您可能认为不会改变这种行为的事情。所有这些都获得完全相同的输出:
select myfunction(b)from mytablewhere myfunction(b) = 2and a = 1;select xfrom ( select myfunction(b) as x from mytable where a = 1)where x = 2;select xfrom ( select myfunction(b) as x from mytable where a = 1)where x = 2;with t (x) as ( select myfunction(b) from mytable where a = 1)select xfrom twhere x = 2;
优化器在内部将它们全部重写为同一查询,您仍然会获得全部七个函数调用。添加未记录的提示会更改它:
with t (x) as ( select myfunction(b) from mytable where a = 1)select xfrom twhere x = 2; X---------- 2 2In function for p=1In function for p=11In function for p=21In function for p=31In function for p=41
但您不能(或不应)真正使用或依赖它。
索引,分区,优化器版本,统计资料等,都将影响到如何对优化器的行为 您的 查询。
和其他需要考虑的事情一样,您可以具有基于函数的索引或确定性函数…
所以…这取决于。



