如何在函数中使用全局临时表?

时间:2019-02-05 19:42:17

标签: sql oracle plsql

所以我有一个接受3个IN参数(小时,日期,代码)的函数  并返回一个数字。

我的功能代码如下:

create or replace FUNCTION     get_max_value    (rhr       NUMBER,
                                                 rdate    VARCHAR2,
                                                 rcode      VARCHAR2)
   RETURN NUMBER
IS
   rvalue_day   NUMBER;
--
BEGIN
   SELECT MAX (v.value)
     INTO rvalue_day
     FROM table v
          JOIN rel_table_1 sv ON (v.value_id = sv.value_id)
          JOIN look_up_table ff ON (sv.form_field_id = ff.form_field_id)
    WHERE     v.date = rdate
          AND v.code = rcode
          AND v.hr_num = rhr
          AND (v.code = 'PASS' OR v.code IS NULL);
   RETURN rvalue_day;
END;

由于性能问题,我试图使用一个全局临时表来获取值(v.value)和与之关联的primary_identifier(value_Id)。我的代码如下:

with  table_c as 
(
  select value, value_id 
    from table where date = rdate 
     AND code = rcode 
     AND hr_num = rhr
 )
select MAX (v.value)
     FROM table_c v
          JOIN rel_table_1 sv ON (v.value_id = sv.value_id)
          JOIN look_up_table ON (sv.form_field_id = ff.form_field_id)
    WHERE     ff.code_desc = rcode;

是否可以将上述方法合并到函数中,以便它可以接受多个参数的值?我目前有一个存储过程,试图通过在这3个参数中插入3个值来得出一个值...

谢谢!

1 个答案:

答案 0 :(得分:2)

这不是您的问题“我如何优化此功能”的答案。

我将向您展示使用函数的想法可能是性能问题的原因-我猜这就是您的情况。


请查看以下非常简单的情况:

create table ttest as 
select * from all_objects
fetch first 10000 rows only;

create index ttest_ix on ttest(object_type);

create or replace function get_max(p_object_type varchar)
return number
is
  ret_val number;
begin
  select max(object_id) into ret_val
  from ttest
  where object_type = p_object_type;
  return ret_val;
end;
/

create or replace view get_max_view as
select object_type, max(object_id) as max_id
from ttest
group by object_type
;

视图get_max_view与功能get_max等效,例如,您可以在查询中以这种方式使用两者:

select object_id, object_type, get_max(object_type) as max_id
from ttest;

select object_id, object_type, 
       (select max_id from get_max_view x where x.object_type = t.object_type) as max_id
from ttest t;

现在,请检查针对10000条记录运行上述两个查询的情况-为此,我将两个查询都嵌套为子查询,并计算所有结果的总和:

set timings on;

select sum(max_id)
from (
    select object_id, object_type, get_max(object_type) as max_id
    from ttest
);

SUM(MAX_ID)
-----------
  214087478

Elapsed: 00:00:11.764

select sum(max_id)
from (
    select object_id, object_type, 
           (select max_id from get_max_view x where x.object_type = t.object_type) as max_id
    from ttest t
);

SUM(MAX_ID)
-----------
  214087478

Elapsed: 00:00:00.011

请检查时间-11.76秒vs. 11毫秒。
这快了1000倍-快100000% !!!

这就是为什么我在评论中建议您用视图替换此functin的原因,因为这很可能是导致性能问题的原因,而尝试优化此功能可能是错误的方法。