Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Oracle PLSQL中使用dbms_xmldom以获得良好的功能性能?_Xml_Oracle_Plsql_Domdocument_Oracle12c - Fatal编程技术网

如何在Oracle PLSQL中使用dbms_xmldom以获得良好的功能性能?

如何在Oracle PLSQL中使用dbms_xmldom以获得良好的功能性能?,xml,oracle,plsql,domdocument,oracle12c,Xml,Oracle,Plsql,Domdocument,Oracle12c,我正在使用Oracle版本12第1版 我一直在尝试编写一个函数来计算以XML形式存储的对象之间的某种距离 为此,我做了以下几点 首先,注册XML模式 BEGIN -- Register the schema DBMS_XMLSCHEMA.registerSchema('http://www.example.com/fvInteger.xsd', '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:elemen

我正在使用Oracle版本12第1版

我一直在尝试编写一个函数来计算以XML形式存储的对象之间的某种距离

为此,我做了以下几点

首先,注册XML模式

BEGIN
-- Register the schema
DBMS_XMLSCHEMA.registerSchema('http://www.example.com/fvInteger.xsd',
'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FeatureVector">
<xs:complexType>
<xs:sequence>
<xs:element name="feature" type="xs:integer" minOccurs="5" maxOccurs="999"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>',
   TRUE, TRUE, FALSE);
END;
/
将以下数据插入上表

ID=1
<FeatureVector><feature>85</feature><feature>-41</feature><feature>29</feature><feature>26</feature><feature>-29</feature><feature>1</feature><feature>-29</feature><feature>-8</feature><feature>15</feature><feature>6</feature><feature>-17</feature><feature>6</feature><feature>-27</feature><feature>8</feature><feature>-12</feature><feature>5</feature></FeatureVector>

ID=2
<FeatureVector><feature>98</feature><feature>77</feature><feature>-127</feature><feature>27</feature><feature>-30</feature><feature>-13</feature><feature>-1</feature><feature>14</feature><feature>-31</feature><feature>-56</feature><feature>-10</feature><feature>6</feature><feature>-10</feature><feature>-12</feature><feature>5</feature><feature>19</feature></

FeatureVector>

... and so on (I am working with 200.000 objects).
这个函数的性能很差。它使用了太多的内存,并且比预期的慢得多(主要是因为使用了对象关系存储)

我甚至得到了一个错误:

ORA-00039:erro durante ac?o periodica ORA-04036:Memoria PGA usada pela实例超出PGA集合限制ORA-06512:em “XDB.DBMS_XMLDOM”,第5027行ORA-06512:em“XDB.DBMS_XMLDOM”,第 5052 ORA-06512:em“HIGIIA.XML\u曼哈顿距离”,第19行

另外,我使用一个查询尝试了下面这个不同的解决方案,但是性能也不好

SELECT SUM( ABS(oFV.feature - iFV.feature) )
  INTO   total
  FROM   XMLTABLE(
           '//FeatureVector/feature'
           PASSING outXML
           COLUMNS rn       FOR ORDINALITY,
                   feature  NUMBER  PATH '.'
         ) oFV
         INNER JOIN
         XMLTABLE(
           '//FeatureVector/feature'
           PASSING innXML
           COLUMNS rn       FOR ORDINALITY,
                   feature  NUMBER  PATH '.'
         ) ifv
         ON ( oFV.rn = iFV.rn );
我可以做些什么来提高它的性能

我确实需要提高性能,而不是解决ORA-00039错误 增加PGA总限额


希望有人能帮忙!提前谢谢

两件事-我猜您的内存不足是因为没有调用DBMS_XMLDOM.freeDocument(docXXX)


但是关于性能问题——如果没有及时的细节,很难说代码是否有问题,或者这是否本质上是解析相关xmltype字段值的预期开销。我的直接印象是,预先计算并存储“距离”值(当插入/更新/删除xml时)。这样,您就可以通过直接sql查询数据,而无需读取端的所有解析开销。如果您想保持xml模式干净,可以将计算出的值存储在xml或关系表中。

谢谢您的回答!它可以被索引(这意味着一些距离将被预先计算并存储在那里),但它使用了大量内存,有时它并不相互干扰。它解决了内存问题并提高了性能(尽管它仍然不是很好)。。。
create or replace FUNCTION myDistance(
  innXML XMLType,
  outXML XMLType
) RETURN number
IS
  total NUMBER := 0;
  docInn xmldom.DOMDocument;
  docOut xmldom.DOMDocument;
  nInn xmldom.DOMNode;
  nOut xmldom.DOMNode;
  nlInn xmldom.DOMNodeList;
  nlOut xmldom.DOMNodeList;
  len number;
BEGIN
--Converte os atributos xmltype para DOMDocuments.
docInn := dbms_xmldom.newDOMDocument(innXML);
docOut := dbms_xmldom.newDOMDocument(outXML);

nlInn := xmldom.getElementsByTagName(docInn, '*');
nlOut := xmldom.getElementsByTagName(docOut, '*');
len := xmldom.getLength(nlInn);

for i in 1..len-1 loop
    nInn := xmldom.item(nlInn, i);
        nOut := xmldom.item(nlOut, i);
    total := total + ABS(xmldom.getNodeValue(DBMS_XMLDOM.getFirstChild(nInn)) - xmldom.getNodeValue(DBMS_XMLDOM.getFirstChild(nOut)));
end loop;

RETURN total;
END;
/
SELECT SUM( ABS(oFV.feature - iFV.feature) )
  INTO   total
  FROM   XMLTABLE(
           '//FeatureVector/feature'
           PASSING outXML
           COLUMNS rn       FOR ORDINALITY,
                   feature  NUMBER  PATH '.'
         ) oFV
         INNER JOIN
         XMLTABLE(
           '//FeatureVector/feature'
           PASSING innXML
           COLUMNS rn       FOR ORDINALITY,
                   feature  NUMBER  PATH '.'
         ) ifv
         ON ( oFV.rn = iFV.rn );