我需要在 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 的值没有任何影响。
我已经经历了LOB 的 PL/SQL 语义 http://docs.oracle.com/cd/E11882_01/appdev.112/e18294/adlob_plsql_semantics.htmOracle 文档的部分 - 它提到了 CLOB 和 VARCHAR2 变量可以在内置函数中使用的方式,但我找不到任何有关这样做可能导致额外内存使用的信息。
有谁知道为什么会发生这种情况,或者我如何做到这一点(即使用 REPLACE 和 CLOB)而不无法释放内存(假设确实发生了这种情况)?
Thanks