为什么在CLOB上使用REPLACE函数导致CACHE_LOBS增加...?

use*_*502 5 oracle plsql clob oracle11gr2

我需要在CLOB变量上使用内置的REPLACE函数作为更大的PL/SQL过程的一部分.我正在使用Oracle 11g R2并且该功能正常工作,因为它根据需要进行替换,但随着过程运行(要处理大约250万条记录),它会严重减慢 - 如:

  • 前20,000条记录:~12分钟
  • 第二个20,000记录:~24分钟
  • 第三个20,000记录:~37分钟
  • 第四万条记录:~52分钟
  • 等等...

在操作期间检查V $ TEMPORARY_LOBS表明CACHE_LOBS的值随着每一行的处理而增加 - 我的假设是这意味着与LOBS相关联的内存(在这种情况下为CLOBS)一旦被使用就不会被释放......?

使用PL/SQL调试器逐步执行代码会发现每次调用REPLACE函数时CACHE_LOBS的值都会增加2.函数调用遵循以下方式:

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 
Run Code Online (Sandbox Code Playgroud)

好像上面的第三行代码正在动态创建更多的CLOB变量.这是因为由于REPLACE函数需要VARCHAR2参数,会发生某种隐式类型转换吗?我已经尝试过使用dbms_lob.copy而不是"clobRTFText:= REPLACE ...等",但它实际上更糟糕(即CACHE_LOBS增加得更快).无论是什么原因,对dbms_lob.freetemporary的调用似乎对CACHE_LOBS的值没有任何影响.

我已经浏览了Oracle文档的LOB部分的PL/SQL语义部分 - 它提到了CLOB和VARCHAR2变量可以在内置函数中使用的方式,但我找不到任何关于这样做可能导致额外内存使用的事情.

有没有人有任何想法为什么会发生这种情况或如何做到这一点(即使用REPLACE与CLOB)没有它无法释放内存(假设确实发生了什么)?

谢谢

Mic*_*ill 2

为什么要按程序执行此操作?看来声明式方法满足了要求。

UPDATE clob_table SET clob_column = REPLACE(clob_column, '<CR>', '\par ');

您可以提供任何WHERE适合您的条款。