Marklogic 空cts:和查询在性能方面如何

Marklogic 空cts:和查询在性能方面如何,marklogic,Marklogic,假设我有一堆医学期刊,其根元素为medicalJournal。所有医学期刊都属于“mj”集合,而“mj”集合只有医学期刊。其他类型的期刊也有自己的收藏(physicsJournal->“pj”) 为了检索所有医学期刊,我编写了世界上最简单的查询: cts:search(/medicalJournal,cts:and-query(())) 然而,我的一位同行说,为什么不对“pj”而不是空的and查询进行集合查询,从而添加一个额外的约束。理由是,这可能会避免获取空的and所做的所有片段ID的列表。

假设我有一堆医学期刊,其根元素为medicalJournal。所有医学期刊都属于“mj”集合,而“mj”集合只有医学期刊。其他类型的期刊也有自己的收藏(physicsJournal->“pj”) 为了检索所有医学期刊,我编写了世界上最简单的查询:

cts:search(/medicalJournal,cts:and-query(()))
然而,我的一位同行说,为什么不对“pj”而不是空的and查询进行集合查询,从而添加一个额外的约束。理由是,这可能会避免获取空的and所做的所有片段ID的列表。尽管我第一次运行集合查询时,查询仪表显示一些列表缓存未命中。
请告诉我应该采取哪种选择?

简短的回答是,
cts:and query(())
没有内在成本,但是集合查询将比可搜索表达式更快。我完全避免使用可搜索表达式,因此我将这样写:

cts:search(collection(), cts:collection-query($journal-collection))
较长的答案是,您可以非常轻松地测试这一点,并从
xdmp:plan
和“xdmp:querymeters”中获得一些好信息。您还可以使用查询分析

让我们先插入一些测试文档。这使用

坐下来等待文档加载。您可以检查
ErrorLog.txt
查看进度,或刷新数据库状态。或者只是看着你的CPU

加载后,这些测试文档包含大量冗余。这使我们能够测试检索文档的不同方法。下面是一个示例:

<?xml version="1.0" encoding="UTF-8"?>
<article>
  <id>mj192462</id>
  <type>mj</type>
  <mj>192462</mj>
  <issue>31</issue>
  <article>432</article>
  <article-ref>589</article-ref>
  <article-ref>812</article-ref>
  <article-ref>316</article-ref>
  <article-ref>512</article-ref>
  <article-ref>380</article-ref>
</article>
请注意,计划中没有与您的
cts:和查询(())
对应的内容?那是因为这是一个角落。像
cts:search(/medicalJournal,cts:和query(())
这样的查询中的实际工作是通过处理可搜索表达式
/medicalJournal
完成的。这可能有助于解释为什么我更喜欢将可搜索表达式保留为
collection()
,并使用
cts:query
参数进行匹配

链接子项
这个术语很有趣,但我们现在不要讨论它

相反,让我们看一下获取mj文章的其他方法。我们可以查询集合
mj
,或者
类型为[.='mj']
的元素,或者查询
测试/mj/
的目录

collection('mj')

cts:search(collection(), cts:collection-query('mj'))

cts:search(collection(), cts:element-value-query(xs:QName('type'), 'mj')

cts:search(collection(), cts:directory-query('test/mj/', 'infinity'))
检查每个表单的
xdmp:plan
输出,我们看到
qry:final plan
显示了前两个表单的两个
术语查询
查找。这看起来很像
mj
上的
元素查询
,但并不总是相同的术语。然后我们看到最后三个都有一个。术语查找驱动了查询的复杂性,因此我们可以说元素查询的复杂性是集合查询的两倍

这基本上回答了你的问题,我认为:
cts:search(collection(),cts:collection query('mj'))
可以比
cts:search(collection(),cts:element query(xs:QName('mj'),cts:and query(())
更快,因为它的术语查找更少

但是,让我们继续使用最后三个选项,看看是否有任何理由使用最后三个选项中的一个或另一个。集合查找和目录查找都使用URI:分别是集合URI和目录URI。这些都是经过大量优化的,因此我们可能期望它们比元素值查找更快

让我们看看是否可以使用
xdmp:querymeters
证明这一点。以如下形式运行最后三个表达式中的每一个:

xdmp:describe(
  cts:search(collection(), cts:collection-query('mj')))
, xdmp:query-meters()
对于本练习,重点关注
xdmp:query meters
对树缓存和列表缓存命中和未命中的说明。不要太注意
经过的时间
,因为这在很大程度上取决于缓存了多少索引数据,我们无法控制这一点。无论如何,您应该在所有三个查询中看到相同的树命中和未命中总数。我看到每个都有9个,但重要的是没有区别,因为结果是一样的。但是列表缓存命中和未命中的总数有所不同。对于集合或目录,它等于数据库中的机架数:在我的例子中是3。但是对于元素值,它是看台数量的两倍:在我的例子中是6。因此,所有其他条件都相同,元素值查找有可能做两倍的I/O。而所有其他条件都不相同:URI查找根本不太可能做任何I/O,因为它们的索引往往总是留在内存中


我们可以得出结论,虽然其他方法都不是非常慢,但通过集合URI或目录URI进行查找是最好的。

简单的回答是,
cts:and query(())
没有固有的成本,但是集合查询将比可搜索表达式更快。我完全避免使用可搜索表达式,因此我将这样写:

cts:search(collection(), cts:collection-query($journal-collection))
较长的答案是,您可以非常轻松地测试这一点,并从
xdmp:plan
和“xdmp:querymeters”中获得一些好信息。您还可以使用查询分析

让我们先插入一些测试文档。这使用

坐下来等待文档加载。您可以检查
ErrorLog.txt
查看进度,或刷新数据库状态。或者只是看着你的CPU

加载后,这些测试文档包含大量冗余。这使我们能够测试检索文档的不同方法。下面是一个示例:

<?xml version="1.0" encoding="UTF-8"?>
<article>
  <id>mj192462</id>
  <type>mj</type>
  <mj>192462</mj>
  <issue>31</issue>
  <article>432</article>
  <article-ref>589</article-ref>
  <article-ref>812</article-ref>
  <article-ref>316</article-ref>
  <article-ref>512</article-ref>
  <article-ref>380</article-ref>
</article>
请注意,计划中没有与您的
cts:和查询(())
对应的内容?那是因为这是一个角落。像
cts:search(/medicalJournal,cts:和query(())
这样的查询中的实际工作是通过处理可搜索表达式
/medicalJournal
完成的。这可能有助于解释为什么我更喜欢将可搜索表达式保留为
collection()
,并使用
cts:query
参数进行匹配

链接子项
这个术语很有趣,但我们现在不要讨论它

相反,让我们看一下获取mj文章的其他方法。我们