如果我构建自己的函数“ myfunction”并执行以下查询:
select myfunction(parameters) from mytable where a and b and c and d
如果mytable有100万行,但是在我之后只有100行。当我执行此查询时,myfunction将执行100或100万行吗?
在这种情况下会发生什么?
select myfunction(parameters) from mytable where a and b and c and d and myfunction(parameters) == e
在第一个示例中,它将仅执行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 as begin dbms_output.put_line('In function for p=' || p); return mod(p,3); end; / set serveroutput on select myfunction(b) from mytable where a = 1; MYFUNCTION(B) ------------- 1 2 0 1 2 In function for p=1 In function for p=11 In function for p=21 In function for p=31 In function for p=41
仅针对与where子句筛选器匹配的行调用该函数。但是,据我所知,这并不能保证。
where
在第二个示例中,它要复杂得多,并且在很大程度上取决于优化程序。在我的简单演示中,优化器(在本例中为11gR2)首先进行评估a,并且仅针对与之匹配的行调用该函数;但随后会再次为select- list值调用它:
a
select myfunction(b) from mytable where a = 1 and myfunction(b) = 2; MYFUNCTION(B) ------------- 2 2 In function for p=1 In function for p=11 In function for p=11 In function for p=21 In function for p=31 In function for p=41 In function for p=41
a=1与以前一样,对五行中的每一行调用该函数,对于myfunction(b) = 2第二次被调用的函数,则调用该函数以获取结果集中的值。
a=1
myfunction(b) = 2
同样,对于此示例,您可能认为不会改变这种行为的事情。所有这些都获得完全相同的输出:
select myfunction(b) from mytable where myfunction(b) = 2 and a = 1; select x from ( select myfunction(b) as x from mytable where a = 1 ) where x = 2; select x from ( select /*+ materialize */ 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 x from t where x = 2;
优化器在内部将它们全部重写为同一查询,您仍然会获得全部七个函数调用。添加未记录的提示会更改它:
with t (x) as ( select /*+ materialize */ myfunction(b) from mytable where a = 1 ) select x from t where x = 2; X ---------- 2 2 In function for p=1 In function for p=11 In function for p=21 In function for p=31 In function for p=41
但您不能(或不应)真正使用或依赖它。
索引,分区,优化器版本,统计资料等,都将影响到如何对优化器的行为 您的 查询。
和其他需要考虑的事情一样,您可以具有基于函数的索引或确定性函数…
所以…这取决于。