大批XSL操作的Oracle性能问题

时间:2010-04-29 15:32:34

标签: performance oracle xslt

我有一个在XMLType对象上执行许多XSL转换的系统。问题是系统会随着时间的推移逐渐减慢,有时在内存不足时会崩溃。看起来减速(可能是内存崩溃)在dbms_xslprocessor.processXSL函数调用周围,逐渐需要更长时间才能完成。

代码如下所示:

v_doc dbms_xmldom.DOMDocument;
v_transformer dbms_xmldom.DOMDocument;
v_XSLprocessor dbms_xslprocessor.Processor;
v_stylesheet dbms_xslprocessor.Stylesheet;
v_clob clob;
...
transformer := PKG_STUFF.getXSL();
v_transformer := dbms_xmldom.newDOMDocument(transformer);
v_XSLprocessor := Dbms_Xslprocessor.newProcessor;
v_stylesheet := dbms_xslprocessor.newStylesheet(v_transformer, '');
...
for source_data in (select id in source_tbl) loop
begin
    v_doc := PKG_CONVERT.convert(in_id => source_data.id);
    --start time of operation
    v_begin_op_time := dbms_utility.get_time;
    --reset the CLOB                    
    v_clob := ' ';
    --Apply XSL Transform
    dbms_xslprocessor.processXSL(p => v_XSLprocessor, ss => v_stylesheet, xmldoc => v_Doc, cl => v_clob);
    v_doc := dbms_xmldom.newDOMDocument(XMLType(v_clob));
    --end time
    v_end_op_time := dbms_utility.get_time; 
    --calculate duration
    v_time_taken  :=  (((v_end_op_time - v_begin_op_time)));
    --log the duration
    PKG_LOG.log_message('Time taken to transform XML: '||v_time_taken);
    ...
    ...
    DBMS_XMLDOM.freeDocument(v_Doc);
    DBMS_LOB.freetemporary(lob_loc => v_clob);
end loop;

转换XML所需的时间正在慢慢增加(我想它也可能是对dbms_xmldom.newDOMDocument的调用,但我认为这是相当简单的)。我不知道为什么.... :(

(Oracle 10g)

更新

通过简单地评论对processXSL的调用进行的进一步测试似乎显着加快了速度。仍然在等待更大的数据集测试来确认这一点,但似乎processXSL正在扼杀事情。有没有其他人有过这个问题?

我们现在没有转换许多XML文档,只有几千个。 XSL并不简单,但我只创建了一个Processor,一个Transformer和一个Stylesheet,然后一遍又一遍地重复使用它们......

更新2:

即使没有转换,内存使用量也在不断增长。几乎不会崩溃,但它仍然不应该这样做。非常令人费解。

更新3:

所以......我们的DBA在dbms_xmldom以及dbms_xslprocessor中可能存在 已知内存泄漏的事实。问题已在较新版本的Oracle中得到修复,但我们没有这些版本,并且由于没有立即升级的计划,我们必须围绕此进行编码。

2 个答案:

答案 0 :(得分:2)

正如我所提到的,看起来我们使用的软件包中存在已知的内存问题,而我使用的Oracle版本没有应用修复程序。我发现我能够围绕它们进行编码。

最初,我使用dbms_xmldom来构建XML文档。我用SELECT(into ... from dual)语句和XML函数替换了这段代码:xmlelementxmlconcatxmlaggxmlforest

要执行转换,XMLType API具有transform函数,我使用该函数代替dbms_xslprocessor包。它运行速度较慢,但​​似乎更加一致(在速度和内存使用方面)并且在内存不足时不会使系统崩溃。 :)

答案 1 :(得分:1)

我的理解是,像XSL处理这样的DOM操作的内存使用往往是令牌数量的第四个幂。

我们还看到XML处理由于内存不足错误而失败 - 在XSL处理中,创建DOM文档等。

因此,我建议您在进行处理时检查DBA的手表内存使用情况并检查其缩放程度。

在我们的例子中,我们的XSL处理一次只需要在文档的相对较小的部分上进行操作。例如,我们提取了100,000个设施的数据,并且XSL在单个设施上转换了数据。通过以1000或5000的组进行处理然后将最终文档拼接在一起,我们能够大大加快速度并减少内存使用量。由于我们使用dbms_xmlgen.getXMLType()从关系表中提取数据来创建XML文档,因此我们可以使用dbms_xmlgen.setMaxRows来设置块大小。

其他语言的一些XSL处理器可以串行化并交换时间和空间以供内存使用。但是,据我所知,数据库版本希望将所有内容整合在一起并进行处理。