在我的制作环境中,当我直接在select中调用函数时,当我“包装”选择然后调用然后在外面调用函数时,我有一个显着的区别(下面我给你看两个简单的例子)
在第一种情况下(直接调用函数时)结果查询在35秒内结束。
在第二种情况下(函数换行),结果在7秒内结束。
当然,查询是完全相同的,结果行也是一样的。
在两种方式中调用相同的函数存在差异(性能)?
慢速版
select col1, col2, myFun(col3)
from aTable;
快速版
select col1, col2, myFun(col3)
from (select col1, col2, col3
from aTable);
答案 0 :(得分:3)
假设aTable中有100万行,但您的真实查询有一个只返回10行的WHERE子句:
select col1, col2, myFun(col3)
from aTable
join ...
join ...
where ...;
Oracle 可能决定在加入和过滤之前调用函数myFun,因此它将被调用100万次。由于上下文切换,从SQL调用PL / SQL函数很慢。
当你像这样包装时:
select col1, col2, myFun(col3)
from (select col1, col2, col3
from aTable
join ...
join ...
where ...
);
...现在Oracle 可能将首先执行连接和过滤,返回10行,然后再调用myFun 10次。
如果每个函数调用需要0.001秒,那么第一次查询将需要1,000,000 * 0.001 = 1,000秒,第二次查询需要10 * 0.001 = 0.01秒。
请注意,我说可能和可能 - 优化工具可以根据统计信息做出不同的选择 - 因此对于某些查询,两个版本只能调用该函数10次,或两者都称它为100万次。
这个提示应该确保第二个版本总是很快,告诉Oracle不要将两个查询合并为一个:
select /*+ no_merge(v) */ col1, col2, myFun(col3)
from (select col1, col2, col3
from aTable
join ...
join ...
where ...
) v;