sql - sql查询中函数的执行顺序是什么?
问题描述
如果我构建自己的函数“myfunction”和这个查询:
select
myfunction(parameters)
from
mytable
where
a and b and c and d
如果 mytable 有 100 万行,但在我的 where 我只有 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
仅对匹配子句过滤器的行调用该函数。但是,据我所知,这并不能保证。
在第二个示例中它相当复杂,并且很大程度上取决于优化器。对于我的简单演示,优化器(在本例中为 11gR2)首先评估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
第二次调用该函数的行,以获取结果集中的值。
同样,对于这个例子,你可能认为会改变这种行为的事情不会。所有这些都得到完全相同的输出:
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
但是您不能(或不应该)真正使用或依赖它。
索引、分区、优化器版本、统计信息等都会影响优化器对查询的行为方式。
和其他要考虑的事情一样,你可以有一个基于函数的索引,或者一个确定性的函数......
所以……这取决于。
推荐阅读
- sql - 使用 SQL 提取 XML 数据
- flutter - Flutter 从“Future”返回“Widget”
" - asp.net-core - 在 asp.net core 3.1 中具有密码保护链接的匿名用户 - ClaimsPrinciple/cookie 是最好的方法吗?
- python - 迭代数据框行时将列表添加到列
- python - Python - 连接到 Gmail 并发送邮件 - 错误 534 InvalidSecondFactor
- image - 某些移动设备无法从 firebase 数据库中检测到图像
- android - 在 Fragment 之间共享 ViewModel 或在 ViewModel 之间共享 LiveData
- bitmap - 谁能简化这个按位表达式
- c# - 设置 LoadedBehavior 时无法控制 MediaElement 手动
- mysql - 购买的前 10 种产品的数量?