我需要在 CLOB 变量上使用内置的 REPLACE 函数作为更大的 PL/SQL 进程的一部分。我正在使用 Oracle 11g R2 并且该功能工作正常,因为它会根据需要进行替换,但是随着过程的运行(大约有 250 万条记录要处理),它会严重减慢 - 如:
- 前 20,000 条记录:~12 分钟
- 第二个 20,000 条记录:~24 分钟
- 第三个 20,000 条记录:~37 分钟
- 第四个 20,000 条记录:~52 分钟
- ETC...
在操作期间检查 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
就好像上面的第三行代码正在动态创建更多的 CLOB 变量。那是因为由于 REPLACE 函数需要 VARCHAR2 参数而发生某种隐式类型转换吗?我尝试使用 dbms_lob.copy 而不是“clobRTFText := REPLACE...etc”,但实际上情况更糟(即 CACHE_LOBS 增加得更快)。不管是什么原因,对 dbms_lob.freetemporary 的调用似乎对 CACHE_LOBS 的值没有任何影响。
我已经浏览了Oracle 文档的PL/SQL Semantics for LOBs部分——它提到了 CLOB 和 VARCHAR2 变量可以在内置函数中使用的方式,但我找不到任何可能导致额外内存使用的内容。
有谁知道为什么会发生这种情况,或者我怎么能做到(即使用带有 CLOB 的 REPLACE)而不会释放内存(假设确实发生了什么)?
谢谢