一尘不染

sql查询中函数执行的顺序是什么?

sql

如果我构建自己的函数“ 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

阅读 159

收藏
2021-03-08

共1个答案

一尘不染

在第一个示例中,它将仅执行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子句筛选器匹配的行调用该函数。但是,据我所知,这并不能保证。

在第二个示例中,它要复杂得多,并且在很大程度上取决于优化程序。在我的简单演示中,优化器(在本例中为11gR2)首先进行评估a,并且仅针对与之匹配的行调用该函数;但随后会再次为select-
list值调用它:

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第二次被调用的函数,则调用该函数以获取结果集中的值。

同样,对于此示例,您可能认为不会改变这种行为的事情。所有这些都获得完全相同的输出:

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

但您不能(或不应)真正使用或依赖它。

索引,分区,优化器版本,统计资料等,都将影响到如何对优化器的行为 您的 查询。

和其他需要考虑的事情一样,您可以具有基于函数的索引或确定性函数…

所以…这取决于。

2021-03-08