У меня есть требование использовать встроенную функцию REPLACE для переменной CLOB как часть более крупного процесса PL/SQL. Я использую Oracle 11g R2, и функция работает нормально, поскольку она выполняет замену по мере необходимости, но по мере выполнения процедуры (для обработки требуется около 2,5 миллионов записей) она сильно замедляется, например:
- первые 20 000 записей: ~12 минут
- секунда 20 000 записей: ~24 минуты
- третьи 20 000 записей: ~37 минут
- четвертые 20 000 записей: ~52 минуты
- и т.д...
Проверка V$TEMPORARY_LOBS во время работы показывает, что значение CACHE_LOBS увеличивается с каждой обрабатываемой строкой. Я предполагаю, что это означает, что память, связанная с LOBS (в данном случае CLOBS), не освобождается после того, как она была использована...?
Пошаговое выполнение кода с помощью отладчика PL/SQL показывает, что значение CACHE_LOBS увеличивается на 2 при каждом вызове функции REPLACE. Вызовы функций соответствуют следующим строкам:
clobRTFText CLOB;
...
dbms_lob.createtemporary(clobRTFText, TRUE, dbms_lob.call);
...
clobRTFText := REPLACE(clobRTFText, '<CR>', '\par '); <== Causes CACHE_LOBS to increase by 2
...
dbms_lob.freetemporary(clobRTFText); <== Doesn't seem to cause CACHE_LOBS to decrease
Как будто третья строка кода выше создает дополнительные переменные CLOB на лету. Это потому, что происходит какое-то неявное преобразование типа из-за того, что функция REPLACE ожидает параметр VARCHAR2? Я пытался использовать dbms_lob.copy вместо "clobRTFText := REPLACE...etc", но на самом деле это было хуже (т.е. CACHE_LOBS увеличивался еще быстрее). Какой бы ни была причина, вызов dbms_lob.freetemporary, по-видимому, не влияет на значение CACHE_LOBS.
Я просмотрел раздел PL/SQL Semantics for LOB в Oracle документация - в ней упоминается способ использования переменных CLOB и VARCHAR2 во встроенных функциях, но я не могу найти ничего об этом, что может привести к дополнительному использованию памяти.
Есть ли у кого-нибудь идеи, почему это происходит или как я могу это сделать (т.е. использовать REPLACE с CLOB), не освобождая память (при условии, что это действительно происходит)?
Спасибо
dbms_lob.createtemporary(clobRTFText, FALSE, dbms_lob.call);
- person Vincent Malgrat   schedule 28.08.2013lob_cache
действительно увеличивается на 2 дляreplace
, но только в первый раз для прицела. Я никогда не вижу, чтобы значение превышало 3 или 4. Предположительно, я делаю что-то другое, поэтому не могли бы вы рассказать, как это вызывается и что еще оно делает? В идеале полная урезанная версия, которая показывает поведение. - person Alex Poole   schedule 28.08.2013