Снижает ли dbms_output.put_line
производительность в plsql
коде?
dbms_output.put_line
Ответы:
Каждая дополнительная строка кода снижает производительность кода. В конце концов, это дополнительная инструкция для выполнения, которая, по крайней мере, потребляет часть процессора. Так что да, dbms_output.put_line снижает производительность.
Реальный вопрос: перевешивает ли польза от этой дополнительной строки кода снижение производительности? Только ты можешь ответить на этот вопрос.
С уважением,
Роб.
Да, это еще один фрагмент кода, который необходимо выполнить, но если вывод не включен, я думаю, что накладные расходы минимальны.
Вот вопрос AskTom с более подробной информацией: Повлияют ли операторы dbms_output.put_line, оставленные в пакетах, на производительность?
Вы можете изучить условную компиляцию, чтобы DBMS_OUTPUT.PUT_LINE находились только в предварительно проанализированный код, если процедура скомпилирована с соответствующей опцией.
Один вопрос: был ли вызван DBMS_OUTPUT.ENABLE. Если это так, любое значение в DBMS_OUTPUT.PUT_LINE будет записано в структуру памяти сеанса. Если вы продолжите помещать туда что-то и никогда не вынимать (что может быть в случае с некоторыми подключениями к серверу приложений), вы можете обнаружить, что через несколько дней у вас будет МНОГО материала в памяти.
Я использую таблицу журналов вместо dbms_output. Обязательно настройте как автономную транзакцию, что-то вроде (конечно, измените для своих нужд):
create or replace package body somePackage as
...
procedure ins_log(
i_msg in varchar2,
i_msg_type in varchar2,
i_msg_code in number default 0,
i_msg_context in varchar2 default null
) IS PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into myLogTable
(
created_date,
msg,
msg_type,
msg_code,
msg_context
)
values
(
sysdate,
i_msg,
i_msg_type,
i_msg_code,
i_msg_context
);
commit;
end ins_log;
...
end;
Конечно, убедитесь, что вы создали свою таблицу журналов. В вашем коде, если вы выполняете много операций в цикле, вы можете захотеть регистрировать только один раз за x число операций, например:
create or replace myProcedure as
cursor some_cursor is
select * from someTable;
v_ctr pls_integer := 0;
begin
for rec in some_cursor
loop
v_ctr := v_ctr + 1;
-- do something interesting
if (mod(v_ctr, 1000) = 0) then
somePackage.ins_log('Inserted ' || v_ctr || ' records',
'Log',
i_msg_context=>'myProcedure');
end if;
end loop;
commit;
exception
when others then
somePackage.ins_log(SQLERRM, 'Err', i_msg_context=>'myProcedure');
rollback;
raise;
end;
Обратите внимание, что автономная транзакция гарантирует, что ваш журнал stmt будет вставлен, даже если произойдет ошибка, и вы откатите все остальное (поскольку это отдельная транзакция).
Надеюсь, это поможет... намного лучше, чем dbms_output ;)
dbms_output.put_line
. 07.02.2011 Это зависит от соотношения того, сколько раз вы вызываете dbms_output.put_line
по сравнению с тем, что еще вы делаете в PL/SQL.
dbms_output.put_line(my_slow_function())
08.02.2011