这里有没有更高效的XQuery删除?
Is there a more efficient XQuery here for deletion?
我有一个大型 eXist-db 数据库,我正在其中实现一些功能来管理内部数据。
这里的相关信息是:
有 2000 位客户。
每个客户可以访问 400 个文档。
现在每个文档都有 20 种语言。
所以我有 2000 个 XML,每个都有这样的内容:
<customer name="foo">
<document num="A01" subscribed="Y">
<languages>
<lang subscribed="N">Arabic</lang>
<lang subscribed="Y">Polish</lang>
... and so on for 400 documents for 20 languages ...
现在我尝试编写一个 xQuery,因为我需要撤销一种语言。这意味着我需要从本质上删除 2000 个文件,对于每个文档,定义了名称的 。
所以像这样:
for $langs in $g:collection.customers//lang[text()=$deletelang]
return update delete $langs
但这需要很长时间,而且实际上需要大量内存。当然在查看它时...$langs 将是 2000*400 = 800,000 个项目。
我会注意到存在一个范围索引,其中包含:
<create qname="lang" type="xs:string" nested="no"/>
但是,删除查询是否效率太低,以至于基本上无法执行 800,000 个项目,还是应该编写其他方式?
更新我
所以我稍微改变了一下,只是为了看看。
1)根据评论,我改为“。”来自文本()
2) 我在其周围添加了 subsequence() 以测试各种尺寸>>
for $langs in subsequence($g:collection.customers//lang[.=$deletelang],1,30000)
1-30000 = 24s
所以 运行 整个集合现在 = 110s
您需要分析查询以确定它花费最多时间的确切位置,但您对 text()
的使用可能会使引擎使用范围索引的能力短路,因此正在加载所有这些文件都存入内存。
text()
选择文本节点,一个元素中可能有多个文本节点。即:element lang { text { 'Pol' }, text { 'ish' } }
将产生一个看起来像 <lang>Polish</lang>
但有两个文本节点的元素,并且会在假设只有一个的谓词上失败:[text() = 'Polish']
。
尝试在谓词中使用点:[. = $deletelang]
。
一次提交如此大的更新也可能在数据库中有额外的开销。如果以原子方式完成删除并不重要,您可以通过批处理更新来提高性能。
我已经有一段时间没有进行大规模删除了。但至少在 eXist 2.2 版中我可以做到:
let $langs := $g:collection.customers//lang[.=$deletelang]
return update delete $langs
没有必要遍历它们。
另外,我会在发布此类大规模删除之前进行完整备份,以确保一切正常。
希望对您有所帮助。
我有一个大型 eXist-db 数据库,我正在其中实现一些功能来管理内部数据。
这里的相关信息是:
有 2000 位客户。
每个客户可以访问 400 个文档。
现在每个文档都有 20 种语言。
所以我有 2000 个 XML,每个都有这样的内容:
<customer name="foo">
<document num="A01" subscribed="Y">
<languages>
<lang subscribed="N">Arabic</lang>
<lang subscribed="Y">Polish</lang>
... and so on for 400 documents for 20 languages ...
现在我尝试编写一个 xQuery,因为我需要撤销一种语言。这意味着我需要从本质上删除 2000 个文件,对于每个文档,定义了名称的
所以像这样:
for $langs in $g:collection.customers//lang[text()=$deletelang]
return update delete $langs
但这需要很长时间,而且实际上需要大量内存。当然在查看它时...$langs 将是 2000*400 = 800,000 个项目。
我会注意到存在一个范围索引,其中包含:
<create qname="lang" type="xs:string" nested="no"/>
但是,删除查询是否效率太低,以至于基本上无法执行 800,000 个项目,还是应该编写其他方式?
更新我
所以我稍微改变了一下,只是为了看看。
1)根据评论,我改为“。”来自文本()
2) 我在其周围添加了 subsequence() 以测试各种尺寸>>
for $langs in subsequence($g:collection.customers//lang[.=$deletelang],1,30000)
1-30000 = 24s
所以 运行 整个集合现在 = 110s
您需要分析查询以确定它花费最多时间的确切位置,但您对 text()
的使用可能会使引擎使用范围索引的能力短路,因此正在加载所有这些文件都存入内存。
text()
选择文本节点,一个元素中可能有多个文本节点。即:element lang { text { 'Pol' }, text { 'ish' } }
将产生一个看起来像 <lang>Polish</lang>
但有两个文本节点的元素,并且会在假设只有一个的谓词上失败:[text() = 'Polish']
。
尝试在谓词中使用点:[. = $deletelang]
。
一次提交如此大的更新也可能在数据库中有额外的开销。如果以原子方式完成删除并不重要,您可以通过批处理更新来提高性能。
我已经有一段时间没有进行大规模删除了。但至少在 eXist 2.2 版中我可以做到:
let $langs := $g:collection.customers//lang[.=$deletelang]
return update delete $langs
没有必要遍历它们。
另外,我会在发布此类大规模删除之前进行完整备份,以确保一切正常。
希望对您有所帮助。