nvl() 函数运行机制,优化案例

来源:互联网 发布:货物进出库软件 编辑:程序博客网 时间:2024/05/16 16:57
nvl(x,y)    运行机制:  当x不为空,还会计算y。

实验验证:
create or replace function f_nvl
     return varchar2
is
     v_char varchar2(22);
begin
        v_char := 'run!';
        dbms_output.put_line(v_char);
       return v_char;
end;
/

select nvl(a, f_nvl()) a from (select 'x' a from dual);
A
---------------------------
x

run!
SQL>  --说明执行了自定义函数

select decode(a, null,f_nvl(),a) a from (select 'x' a from dual);   

A
--------------------
x

SQL>       --decode没有输出"run!",说明它不执行自定义函数。

案例:
--case2:
--一个统计结果的代码,每个月执行一次
SELECT   PROVCODE AS PROV_ID, --省份
            AREACODE AS AREA_ID, --地区
            LIMITINADDLIST AS MAIL_NOTIFY_TYPE_ID,
            COUNT(DISTINCT USERNUMBER) AS LIMITINADDLIST_UCNT
  FROM ODSVIEW.VW_ODS_MAIL_NOTIFY_LIMIT
WHERE SERVICEID = 10
   AND STAT_MONTH = :B1
GROUP BY PROVCODE, AREACODE, LIMITINADDLIST;

机器的配置:256G 内存,RAC, AIX 128CPU
却要跑4个小时,why ?

--因为视图里,有两个自定义函数:
create or replace view odsview.vw_ods_mail_notify_limit as
Select STAT_MONTH ,
       USERNUMBER ,          --手机号
       SERVICEID ,
       nvl(PROVCODE,  getprovcode(USERNUMBER)) AS PROVCODE  ,
       nvl(AREACODE , getareacode(USERNUMBER)) AS AREACODE ,
       NOTIFYTYPE ,
       CASE
           WHEN  notifytype<>9 THEN NOTIFYTYPE
           WHEN  notifytype = 9 AND (limitinaddlist =-1 OR limitinaddlist  IS null) THEN 0
           ELSE  limitinaddlist
           END   limitinaddlist,
       CASE
           WHEN  notifytype<>9 THEN NOTIFYTYPE
           WHEN  notifytype = 9 AND (LIMITNOTINADDLIST =-1 OR LIMITNOTINADDLIST  IS null) THEN 0
           ELSE  LIMITNOTINADDLIST
           END   LIMITNOTINADDLIST
From datasync_prc.ODS_MAIL_NOTIFY_LIMIT;  --6亿数据,字段少,13个G

     
nvl()那两列是为了确认省份,地市是否为空
datasync_prc.ODS_MAIL_NOTIFY_LIMIT 这里为什么没有算好?
因为有垃圾数据,6亿里面只有几条数据没有省份、地区。

优化方案: 将nvl() 函数用decode() 替换。

--by 七年



0 0