Oracle SQL - 在 clob 类型列中计算 XML 个节点

Oracle SQL - Count XML nodes in a clob type column

我试图编写一个优化的 SQL 查询来计算 clob 类型列中的特定 XML 节点,现在我正在使用 REGEXP_COUNT 浏览所有行和所有 XMLs,但这非常慢。

像这样:

SELECT sum(REGEXP_COUNT(clobtype_column_withXMLs, '/Node_Closing_tag', 1)) as 'Node_number' FROM MY_TABLE;

这行得通,但是有数亿个标签,这确实需要很长时间。

我想绕过XML结构,缩短计数时间。我发现了一些东西,但其中大部分涉及将列类型更改为 xml 并使用 xquery 和其他 DML 函数。
在我的例子中,我无法修改 table,我只需要数字,即指定节点在列中出现的次数。

我的table结构:

不是 XML Table,各种列类型和 CLOB type column,其中每一行包含不同大小的 XML(数亿个字符)。 XML 结构比较复杂,我要找的节点在中间:

1/2/3/4/5/I'm_searching_for_this/contains_multiple_nodes

有没有什么快速的方法可以在不修改 table 中的任何内容的情况下对这样的结构中的节点进行计数?快速我的意思是,最多在几个小时内计算 5 亿个节点。 (文本搜索需要 24 小时以上)

替换和测量长度差异 技巧应该为您工作,结果与 REGEXP_COUNT 相同(当您 解析XML并统计元素,应该是最终精度)。

REPLACE 方法的优点是它的实施速度最快。

简单

  • NULL

  • 替换原始字符串中每个出现的搜索子串
  • 计算原串与替换串的长度差

  • 结果除以子串长度得到结果count

.

select 
 sum(REGEXP_COUNT(clobtype_column_withXMLs, '/Node_Closing_tag', 1)) cnt1,
 sum( (length(clobtype_column_withXMLs) - length(replace(clobtype_column_withXMLs,'/Node_Closing_tag',null)))  / length('/Node_Closing_tag')) cnt2
from tst

我建议使用不同的搜索子字符串进行一些测试

 /tag
 tag/
 <tag>
 </tag>
 <tag/>

并比较结果,看看这个方法是否可靠。

您不必更改 table 中的列类型即可使用 XML 查询,您可以使用 XMLQuery 或 XML表.

一种选择是使用XML表提取所有相关节点,并计算返回的节点数:

select count(*)
from your_table
cross join xmltable(
  '//targetNodeName'
  passing xmltype(clobtype_column_withXMLs)
  columns dummy varchar2(1) path '@dummy'
);

XML表为每个匹配节点生成一行。由于您只对它们进行计数,而不使用该节点的内容,因此我使用了虚拟列名称和内容,选择了一个可能不存在的属性名称——如果可能,将其更改为其他名称。 dummy 值因此将为空,但 count(*) 无论如何都会计算它们。

当然必须测试它的性能如何……它可能比使用正则表达式更糟糕。不过,它会允许您搜索自闭标签,根据您当前正在做的事情,这对您来说可能无关紧要。

如果有用的话,您还可以调整它以计算原始 table 中每个 CLOB/XML 值中的节点;例如,如果它有一个 ID 列:

select t.id, count(*)
from your_table t
cross join xmltable(
  '//targetNodeName'
  passing xmltype(clobtype_column_withXMLs)
  columns dummy varchar2(1) path '@dummy'
)
group by t.id;