Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 基于profiler结果的Marklogic查询优化_Performance_Xpath_Xquery_Marklogic - Fatal编程技术网

Performance 基于profiler结果的Marklogic查询优化

Performance 基于profiler结果的Marklogic查询优化,performance,xpath,xquery,marklogic,Performance,Xpath,Xquery,Marklogic,嗨,外面的记录员们 我还有一个问题要问你!我有一套包含邮政编码信息的文件。40万份文件。每个文档订购一个邮政编码,每个文档包含400个功能,按类别和变量排序,如下所示: <postcode id="9728" xmlns="http://www.nvsp.nl/p4"> <meta-data> <!-- Generated by DIKW for NetwerkVSP ST!P --> <version>0.3</version> &l

嗨,外面的记录员们

我还有一个问题要问你!我有一套包含邮政编码信息的文件。40万份文件。每个文档订购一个邮政编码,每个文档包含400个功能,按类别和变量排序,如下所示:

<postcode id="9728" xmlns="http://www.nvsp.nl/p4">
<meta-data>
<!--
Generated by DIKW for NetwerkVSP ST!P
-->
<version>0.3</version>
<dateCreated>2014-06-28+02:00</dateCreated>
</meta-data>
<category name="Oplages">
<variable name="Oplage" updated="2014-08-12+02:00">
  <segment name="Bruto">1234</segment>
  <segment name="Stickers">234</segment>
  <segment name="Netto">1000</segment>
  <segment name="Aktief">J</segment>
</variable>
</category>
<category name="Automotive">
<variable name="Leaseauto">
<segment name="Leaseauto">2.68822210725987</segment>
</variable>
<variable name="Autotype">
<segment name="De Oudere Stadsrijder">4.61734781858941</segment>
<segment name="De Dure Tweedehandsrijder">6.02534919813761</segment>
<segment name="De Autoloze">41.187790998448</segment>
<segment name="De Leasende Veelrijder">0.608035868253147</segment>
<segment name="De Modale Middenklasser">13.1996896016555</segment>
<segment name="De Vermogende Autoliefhebber">4.45283669598206</segment>
<segment name="De Vermogende Kilometervreter">2.07690981203656</segment>
<segment name="De Doelmatige Budgetrijder">17.2048629073978</segment>
<segment name="De Doorsnee Nieuw Kopende Automob">10.1595102603897</segment>
</variable>
...
400 more cat/var/segment element
...
</postcode>
现在,如果我分析这个测试查询,那么慢的部分是在cts:search返回的de文档中查找“Bruto”段。我知道我应该避免通过xpath在文档中查找元素,但我不知道如何将这两个位结合起来,只命中索引

探查器结果:

.main:13:44 1446    27  7127    30  7938    @name = "Bruto"
.main:12:44 1446    27  6956    30  7793    @name = "Bruto"
.main:17:11 1   9.3     2431    9.4     2458    cts:search(fn:collection()/p4ns:postcode, cts:element-attribute-range-query(xs:QName("p4ns:segment"), fn:QName("", "name"), "=", $segment))
.main:10:16 1   7.2     1874    7.2     1885    cts:search(fn:collection()/p4ns:postcode, cts:element-attribute-value-query(xs:QName("p4ns:postcode"), fn:QName("", "id"), ("2311", "2312", "2313")))
查询结果:

1234
4567
3456
现在我的问题是:

1) “@name=“Bruto”是什么意思?为什么速度慢

2) 理想情况下,我会将搜索文档与通过xpath查找段元素结合成一个组合,但如果我将$zoeker放入cts:search中,它是不可搜索的。。。什么是一次性获得结果的最佳方法

提前谢谢


hugo

我发现了两个基本问题:访问数据库的次数太多,而这些访问带回的数据太多,而这些数据都不是你真正想要的。目标是最小化数据库查找的数量,并使每次查找尽可能精确

在这种情况下,执行数据库查找的主要方式是
cts:search
。其中有几种:可能太多了,有时结果从未使用过。我认为其中一些是剩余的实验。在评测时,评测干净的代码很重要

接下来,分析器的大部分时间都在
@name=$segment
XPath谓词中。这也重复了一遍,没有什么好的理由。摆脱重复,它会走得更快

然而,另一个出现的原因是MarkLogic索引文档,而不是节点。它对节点的名称和值进行索引,但每个索引条目都指向一个文档——或者更具体地说是一个片段,但我们不必赘述。因此,当一个文档中有几十个或数百个
segment/@name
值的索引项时,所有这些索引项都指向文档根。如果只要求与特定名称匹配的段,则索引查找将与整个文档匹配。因此,评估必须遍历每个文档树。这在CPU周期上可能会很昂贵,这就是探查器向您展示的内容

如果不重新构造文档,或者不巧妙地处理共现,就无法解决这个问题。但是,我们可以清理您的查询,并使用完整路径将其转换为单个XPath表达式。让我们看看这对于您的用例来说是否足够快

declare namespace p4ns="http://www.nvsp.nl/p4" ;

(: These might be external parameters. :)
let $segment := "Bruto"
let $ids := ("2311","2312","2313")
return collection()/p4ns:postcode[
  @id = $ids]/p4ns:category/p4ns:variable/p4ns:segment[
  @name = $segment]/string()
如果插入示例XML并将其id更改为
2313
,则返回单个值
1234
。分析它在不到1毫秒的时间内显示了33个表达式,其中66%的时间是通过XPath进行数据库查找的。然而,它仍然需要查看所有的
段/@name
值:在本例中,14个值占用了10%的时间

请注意,我没有使用
cts:search
或任何范围索引。MarkLogic自动为XPath值相等查找的节点值编制索引。对于特殊操作,您只需要范围索引:例如facet、排序和不等式查找

你可以做得更好一点:

(collection()/p4ns:postcode[
  @id = $ids]/p4ns:category/p4ns:variable/p4ns:segment[
  @name = $segment])[1]/string()
现在我们告诉评估者,只需要一个匹配项。因此,它将在找到
Bruto
后停止,这是文档的早期内容。在本例中,它是第一个表达式,但平均而言,
(…)[1]
应该将表达式的数量减少一半。其他树修剪技术也应该有所帮助:例如,您可以将
类别
变量
名称添加到输入中,并将它们表示为XPath谓词

这可能是一个很好的时间,让你备份,看看大局。您试图通过此查询实现什么?可能有一种更有效的方式来实现你的目标

如果这是您最常见的用例,那么理想情况下您应该重新构造文档,以便每个id段查找都成为可计算的
doc($uri)
调用。我不确定在这种情况下这是一个好主意,但我不完全了解你的申请

另一种方法是使用内存中的值索引,并避免查看XML。然而,这是一个复杂的方法,我不打算在这里探讨它

(collection()/p4ns:postcode[
  @id = $ids]/p4ns:category/p4ns:variable/p4ns:segment[
  @name = $segment])[1]/string()