Это не ответ на ваш вопрос «как я могу оптимизировать эту функцию».
Я собираюсь показать вам, что сама идея использования функции может бытьпричина ваших проблем с производительностью - и я предполагаю, что это так и есть в вашем случае.
Пожалуйста, посмотрите на приведенный ниже очень простой случай:
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% быстрее !!!
Вот почему я предложил вам в комментарии заменить эту функцию на представление, потому что это наиболее вероятная причина ваших проблем с производительностью,и пытается оптимизировать этофункция, вероятно, неправильный путь.