我有一个大型的eXist-db数据库,正在其中实现一些功能来管理内部数据。
此处的相关信息是:
有2000个客户。
每个客户可以访问400个文档。
现在每个文档有20种语言。
所以我有2000个XML,每个都有这样的东西:
def validate_color(base_colors, color):
"""
Validate a color.
"""
return color.split()[-1] in base_colors
if validate_color(base_colors, color):
...
现在我正尝试编写xQuery,因为我需要撤消某种语言。这意味着我实际上需要在2000个文件中删除每个定义了名称的
是这样的:
<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 ...
但是这是永远的,实际上需要大量的内存。当然,在查看时……$ langs将是2000 * 400 = 800,000个项目。
我会注意到存在一个范围索引,其中包含:
for $langs in $g:collection.customers//lang[text()=$deletelang]
return update delete $langs
但是,删除查询是否仍然如此低效,以至于本质上它无法执行800,000个项目,还是还有其他写方法?
更新我
所以我做了些改动,只是看一下。
1)根据评论,我更改为“。”来自text()
2)我在此周围添加了subsequence()以测试各种尺寸>>
<create qname="lang" type="xs:string" nested="no"/>
1-30000 = 24秒
所以现在运行整个集合= 110s
答案 0 :(得分:1)
您需要对查询进行分析以确定确切的时间在哪儿花费最多,但是使用text()
可能会缩短引擎使用范围索引的能力,因此会加载所有这些内容文档存入内存。
text()
选择文本节点,并且一个元素中可能有多个文本节点。即:element lang { text { 'Pol' }, text { 'ish' } }
将产生一个看起来像<lang>Polish</lang>
的元素,但具有两个文本节点,并且在假设只有一个的谓词上将失败:[text() = 'Polish']
。
尝试在谓词[. = $deletelang]
中使用点。
一次提交如此大的更新还可能导致数据库中存在额外的开销。如果不重要的一点是自动删除,则可以通过分批更新来提高性能。
答案 1 :(得分:0)
已经有一段时间了,因为我不得不进行批量删除。但是至少在eXist 2.2版中我可以做到:
let $langs := $g:collection.customers//lang[.=$deletelang]
return update delete $langs
没有必要遍历它们。
另外,在发出这种大规模删除操作之前,我将进行完整备份,以确保一切正常。
希望这会有所帮助。