Xquery 优化
Posted
技术标签:
【中文标题】Xquery 优化【英文标题】:Xquery optimization 【发布时间】:2016-08-05 15:21:23 【问题描述】:我有这个 xquery 如下:
declare variable $i := doc()/some-element/modifier[empty(modifier-value)];
$i[1]/../..;
我需要在 Marklogic 的 Qconsole 上运行此查询,我们有 721170811 条记录。由于这是大量的记录,我收到超时错误。有什么方法可以优化此查询以获得结果?
附:我不能要求 amdin 增加超时时间。
【问题讨论】:
【参考方案1】:尝试创建一个元素范围索引(如果目标元素不是唯一的,则创建一个路径范围索引)并使用 cts:values() 词典查找。
这样,请求可以从范围索引中读取值,而不必读取每个文档。
见:
http://docs.marklogic.com/guide/search-dev/lexicon
【讨论】:
由于我无法请求管理员,有什么办法可以优化我的代码吗? 拥有 7 亿个文档,如果您需要频繁运行查询,最好的策略是说服管理员添加范围索引。否则,一种替代方法是使用 cts:uris() 函数,将一些元素标准作为 cts:query 传递,以在客户端中收集文档 uri。然后,遍历页面中的 uris 列表,一次从一页文档中检索值。您可以使用 REST API 值端点来执行 cts:query 和 REST API 文档端点,并通过转换来提取值。【参考方案2】:您可以使用 xdmp:spawn,在进行查询时创建一个库,获取文档,迭代结果,每次迭代收集 1000 个文档,然后调用另一个 xdmp:spawn 来处理来自该数据集的信息,我建议总结一下结果只返回您不需要使浏览器崩溃的信息,最后应该如下所示:
xdmp:spawn("process.xqy")
进入库process.xqy
function local:start-process()
let $docs := (....)
let $temp := for $x in $docs[$start to $end]
return local:process-dataset($temp) (: Could use spawn here too if you want :)
return xdmp:spawn("collect.xqy",$temp)
local:start-process()
compact-data 函数应该使用您的数据创建一个文件或一组文件,这样服务器将运行所有进程,并且在几分钟后您就可以毫无问题地查看您的数据。
【讨论】:
【参考方案3】:你不想运行像doc()
或xdmp:directory
这样的东西——只是返回一个每次都会杀死你的结果集。您需要将结果集降低很多。
一些想法:
您希望在 MarkLogic 的 d-node
中完成尽可能多的工作,而在 e-node
中完成的工作尽可能少。这是一种过度概括的方式,但在大多数情况下,我认为d-node
的东西是数据、索引、词典工作等。e-node
的东西处理 xQuery 等。所以,在你的例子中,你肯定比你需要的更多地计算出e-node
。
您将要使用cts:search
,因为它使用索引而不是 xPath 来解析您的查询。所以,是这样的:
declare variable $i := cts:search(fn:collection(),
cts:element-query(xs:QName("some-element"),
cts:element-value-query(xs:QName("modifier"), "", "exact")
)
)[1];
这将返回document-node
's,它看起来就像你想要的$i[1]/../..
。这会在 xPath some-element
中搜索为空的 modifier
。
【讨论】:
【参考方案4】:如果您熟悉marklogic,请创建元素范围索引和属性范围索引并使用cts:search,这样您编写查询将很容易。
【讨论】:
以上是关于Xquery 优化的主要内容,如果未能解决你的问题,请参考以下文章