几乎相同的 XQuery (exist-db) 查询在速度上存在巨大差异

Massive differences in speed with virtually identical XQuery (exist-db) interogations

在过去的几周里,我一直在移植一个 SQL 数据库,虽然我到目前为止设法克服了所有以前的障碍运行,但我现在 运行 进入官方文档、在线搜索和常识都无法帮助的东西。

简而言之,我有一个相当大的集合(大约 9 万个条目,分布在 20 个文件中),大多数条目看起来像这样(这是一个巨大的简化,所以我可以理解这一点):

<document>
 <document_id>Numerical Value</document_id>
 <page_id>Some other numerical value</page_id>
</document>

然后我通过 php 传递一个值,我们称之为 $val st运行ge 部分是当我 运行 标准查询

$p in collection("/db/folder_location")//documentset/document[xs:integer(document_id) eq $val]

无论我传递什么值,它 return 都会在几秒钟内完成所有结果。但是,如果我稍作修改,则可以:

$p in collection("/db/folder_location")//documentset/document[xs:integer(page_id) eq $val]

它要么需要超过 30 秒才能 return 值,要么只是保持锁定在 运行ning 查询中并且永远不会 return 任何东西。在我已经转换的所有 30 个查询中,这是我唯一一次 运行 遇到这个问题并且找不到解决方法。

为了解决查询性能问题,我建议对您的查询进行一些更改 and/or 在 document_idpage_id 元素上添加范围索引。

您的查询将所有 document_idpage_id 元素转换为 xs:integer。给定一个大数据集,这是一个低效的操作。考虑 (a) 删除此类型转换,(b) 将其反转(将 $val 转换为 xs:string),或 (c) 在这两个元素上添加一个范围索引,使用 type="xs:integer"。后一个选项将允许您删除谓词中的强制转换(允许您将其更改为 document[document_id eq $val]document[page_id eq $val]),并且索引应该大大加快查找速度。

要为您的查询添加范围索引,请创建一个 collection 配置文档,如下所示:

<collection xmlns="http://exist-db.org/collection-config/1.0">
    <index xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <range>
            <create qname="document_id" type="xs:integer"/>
            <create qname="page_id" type="xs:integer"/>
        </range>
    </index>
</collection>

如果您的数据在 /db/folder_location 中,则将此文档作为 collection.xconf 存储在 /db/system/config/db/folder_location 中。然后用 xmldb:reindex("/db/system/config/db/folder_location") 重新索引你的 collection。正如关于范围索引的文档所述,有了这个索引定义:

indexes will be used automatically for general or value comparisons as well as string functions like fn:contains, fn:starts-with, fn:ends-with.

有关 eXist 中范围索引的更多信息,请参阅 https://exist-db.org/exist/apps/doc/newrangeindex.xml. For query optimization techniques, see https://exist-db.org/exist/apps/doc/tuning.xml. For indexes in general in eXist, see https://exist-db.org/exist/apps/doc/indexing.xml