XQuery:最有效的迭代方式只在需要时?

时间:2012-12-24 20:35:30

标签: xml for-loop xquery exist-db

这是我的例子:例如,如果我有一个包含500.000条目的非常大的XML文件,如下所示:

<entries>
  <entry id="1">...</entry>
  <entry id="2">...</entry>
  <entry id="3">...</entry>
  ...
  <entry id="500000">...</entry>
</entries>

但我只想保留其ID之间的条目,例如500和1000.当然我会这样做:

let $entries := //entry[(xs:integer(./@id) >= 500) and (xs:integer(./@id) <= 1000)]

但是我猜这个请求后我将继续寻找条目#1000到500.000之后。当我到达这个条目#1000时,它是一种停止寻求的方式吗?

2 个答案:

答案 0 :(得分:1)

如果entry元素按其id属性排序(如提供的文档中所述),则大多数XPath(和XQuery)实现应该有效地评估:< / p>

/*/entry[position() le 1000 and position() ge 500]

答案 1 :(得分:1)

由于您在评论中注意到您正在使用eXist-db,因此我请提供一些特定于eXist-db的指南:

  1. subsequence()函数的性能优于大于/小于/小于方法。有关这方面的讨论,请参阅这篇关于eXist-db邮件列表的Wolfgang Meier的帖子,主题为“优化快速分页的位置谓词”:http://markmail.org/message/aoe5wmy2gmf3aaqh。所以在你的情况下:

    let $entries := subsequence(//entry, 500, 500)
    

    这将为您输入500-1000。

  2. 如果您确实需要进行比较查询(大于/小于),您可能需要在@id上添加范围索引。有关范围索引以及如何设置它们的更多信息,请参阅范围索引的eXist-db文档页面:http://exist-db.org/exist/apps/doc/indexing.xml#rangeidx

  3. 请随时加入eXist-db邮件列表;我们总是很乐意讨论优化查询性能的方法。加入https://lists.sourceforge.net/lists/listinfo/exist-open,或在http://exist.markmail.org/搜索档案。