5

我需要在 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)而不会释放内存(假设确实发生了什么)?

谢谢

4

1 回答 1

1

为什么要在程序上这样做?似乎声明性方法可以满足要求。

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

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

于 2013-09-04T16:09:54.907 回答