首页 > 解决方案 > Oracle 函数性能明显比子查询差

问题描述

我有一个公式需要重复使用才能获得某个日期。下面的示例是出于演示目的而编写的。

select max(order_date)
from orders
where processing_date < sysdate
; 

我希望在一系列进程/脚本中访问此结果,因此认为最好将其封装在一个函数中:

create or replace FUNCTION F_GET_DATE RETURN DATE AS 
    D_DATE DATE;
BEGIN

    select max(order_date)
    INTO D_DATE
    from orders
    where processing_date < sysdate
    ; 
    
  RETURN D_DATE;
  
END F_GET_RF;

但是,当我尝试在 Where 子句中使用它时,性能明显低于我刚刚使用子查询时的性能。问题是,我不想在很多不同的地方使用子查询,以防逻辑发生变化,再加上 DRY 等等......

这似乎无限期地运行:

select *
from order
where order_date = F_GET_DATE;

但是,这可以正常运行

select *
from order
where order_date = (select max(order_date)
                    from orders
                    where processing_date < sysdate);

我也可以毫无问题地查询 Select 中的函数:

select f_get_date
from dual;

我可以做些什么来使该功能“工作”。我不明白为什么表演会受到如此巨大的打击。

标签: sqloracle

解决方案


这是一个非常大的话题,有很多细微差别。简而言之,您需要阅读“PL/SQL 上下文切换”、SQL 中 PL/SQL 函数的一致性、优化技术如PRAGMA UDFRESULT_CACHE、 ordeterministic子句等。

例如你可以阅读我的系列: http: //orasql.org/2013/03/13/deterministic-function-vs-scalar-subquery-caching-part-3/


推荐阅读