在oracle中使用用户定义的函数时,查询需要很长时间选择

时间:2018-03-15 12:28:45

标签: oracle plsql

我有一个函数,它将从表中获得最多三个日期。

create or replace FUNCTION fn_max_date_val(
    pi_user_id IN number)
  RETURN DATE
IS
  l_modified_dt      DATE;
  l_mod1_dt  DATE;
  l_mod2_dt DATE;
  ret_user_id        DATE;
BEGIN

  SELECT MAX(last_modified_dt)
  INTO l_modified_dt
  FROM table1
  WHERE id = pi_user_id;
  -- this table contains a million records
  SELECT nvl(MAX(last_modified_ts),sysdate-90)
  INTO l_mod1_dt
  FROM table2
  WHERE table2_id=pi_user_id;
  -- this table contains clob data, 800 000 records, the table 3 does not have user_id and has to fetched from table 2, as shown below
  SELECT nvl(MAX(last_modified_dt),sysdate-90)
  INTO l_mod2_dt
  FROM table3
  WHERE table2_id IN
    (SELECT id FROM table2 WHERE table2_id=pi_user_id
    );
  execute immediate 'select greatest('''||l_modified_dt||''','''||l_mod1_dt||''','''||l_mod2_dt||''') from dual' into ret_user_id;
  RETURN ret_user_id;
EXCEPTION
WHEN OTHERS THEN
   return SYSDATE;
END;

此功能完美无缺,并在一秒钟内执行。

-- random user_id , just to test the functionality
SELECT fn_max_date_val(100) as max_date FROM DUAL 

MAX_DATE
--------
27-02-14 

为了参考目的,我使用了表名作为table1,table2和table3,但我的商业案例与我在下面说的相似。

我需要获取table1的详细信息以及三个表中最高的修改日期。

我做了类似的事。

SELECT a.id,a.name,a.value,fn_max_date_val(id) as max_date 
FROM table1 a where status_id ='Active';  

以上查询执行完全正常并以毫秒为单位得到结果。但是当我试图使用order by时,问题出现了。

SELECT a.id,a.name,a.value,a.status_id,last_modified_dt,fn_max_date_val(id) as max_date 
FROM table1 where status_id ='Active' a 
order by status_id desc,last_modified_dt desc ;  
-- It took almost 300 seconds to complete

我尝试使用index还包含status_id和last_modified的所有值,但没有运气。这可以以正确的方式完成吗?

2 个答案:

答案 0 :(得分:0)

如果您不使用此功能并执行以下操作,该怎么办:

null

语法可能包含错误,但类似于派生表中的第三个表。

答案 1 :(得分:0)

如果你的查询是这样的,怎么样?

select a.*, fn_max_date_val(id) as max_date 
  from
    (SELECT a.id,a.name,a.value,a.status_id,last_modified_dt
       FROM table1 where status_id ='Active' a 
      order by status_id desc,last_modified_dt desc) a;