Вы не должны увеличивать время ожидания, чтобы скрыть проблему.Вы точно определили проблему с производительностью - это то, что должно быть исправлено, а не скрыто под ковриком.
Две вещи, которые нужно сделать:
Получить трассировку SQL сохраненногопроцедура.
exec dbms_monitor.session_trace_enable(binds => false, waits => true);
exec poor_performing_procedure();
exec dbms_monitor.session_trace_disable();
Посмотрите, как часто выполняются операторы и сколько времени уходит на их выполнение.
Добавление в код хуков в DBMS_PROFILERдля хранимой процедуры.
У меня есть такой код во всех моих пакетах, чтобы я мог определить, нужно ли их профилировать, установив переменную пакета:
PROCEDURE profiler_control(p_start_stop IN VARCHAR2, p_run_comm IN VARCHAR2, p_ret OUT BOOLEAN) AS
l_ret_code INTEGER;
BEGIN
l_ret_code:=dbms_profiler.internal_version_check;
IF l_ret_code !=0 THEN
p_ret:=FALSE;
ELSIF p_start_stop NOT IN ('START','STOP') THEN
p_ret:=FALSE;
ELSIF p_start_stop = 'START' THEN
l_ret_code:=DBMS_PROFILER.START_PROFILER(run_comment1 => p_run_comm);
IF l_ret_code=0 THEN
p_ret:=TRUE;
ELSE
p_ret:=FALSE;
END IF;
ELSIF p_start_stop = 'STOP' THEN
l_ret_code:=DBMS_PROFILER.FLUSH_DATA;
l_ret_code:=DBMS_PROFILER.STOP_PROFILER;
IF l_ret_code=0 THEN
p_ret:=TRUE;
ELSE
p_ret:=FALSE;
END IF;
END IF;
END profiler_control;
Таким образом, внутри процедур есть код, подобный следующему:
create or replace procedure poorly_performing_procedure()
begin
if run_profiler then
profiler_control('START', 'poorly_performing_procedure', g_retval);
end if;
...
if run_profiler then
profiler_control('STOP', 'poorly_performing_procedure', g_retval);
end if;
end poorly_performing_procedure;
/
Oracle предоставляет сценарии (один с именем profiler.sql
), которые можно использовать для получения красивых отчетов, показывающих, сколько раз каждая инструкция / операция PL / SQL былавыполняется во время пробега.Вот ссылка на документацию DBMS_PROFILER для 10g.