Как использовать глобальную временную таблицу в функции? - PullRequest
0 голосов
/ 05 февраля 2019

поэтому у меня есть функция, которая принимает параметры 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 голосов
/ 06 февраля 2019

Это не ответ на ваш вопрос «как я могу оптимизировать эту функцию».

Я собираюсь показать вам, что сама идея использования функции может бытьпричина ваших проблем с производительностью - и я предполагаю, что это так и есть в вашем случае.


Пожалуйста, посмотрите на приведенный ниже очень простой случай:

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 секунды против 11 миллисекунд.
Это более 1000в разы быстрее - 100000% быстрее !!!

Вот почему я предложил вам в комментарии заменить эту функцию на представление, потому что это наиболее вероятная причина ваших проблем с производительностью,и пытается оптимизировать этофункция, вероятно, неправильный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...