在eXist-db中使用范围索引提高查询性能

时间:2016-07-13 18:55:09

标签: xquery exist-db

阅读文档http://exist-db.org/exist/apps/doc/indexing.xml 我发现很难理解如何以及如何改善“阅读”的表现。查询(带有2个参数:字符串和整数)。 eXist-db是否有默认的结构索引?我可以使用'范围索引'?

改进2参数查询

关于我的XML数据库的更多细节(请注意,有两个不同的dbs只是在同一个根目录上合并):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<db>
    <docs>
        <doc>
            <header>
                <year>2001</year>
                <number>1</number>
                <type>O</type>
            </header>
            <metas>
                <meta>
                    <number>26001</number>
                    <details>
                        <detail>
                            <description>legge</description>
                            <number>19</number>
                            <date>14/01/1994</date>

                        </detail>
                        <detail>
                            <description>decreto legge</description>
                            <number>453</number>
                            <date>15/11/1993</date>
                        </detail>
                    </details>
                </meta>
            </metas>
        </doc>
        <doc>
            <header>
                <year>2001</year>
                <number>2</number>
                <type>O</type>
            </header>
            <metas>
                <meta>
                    <number>26002</number>
                    <details>
                        <detail>
                            <description>decreto legislativo</description>
                            <number>29</number>
                            <date>03/02/1993</date>
                        </detail>
                    </details>
                </meta>
                <meta>
                    <number>26016</number>
                    <details>
                        <detail>
                            <description>decreto legislativo</description>
                            <number>29</number>
                            <date>03/02/1993</date>

                        </detail>
                    </details>
                </meta>
            </metas>
        </doc>
    </docs>



    <full_text_docs>
        <doc>
            <header>
                <year>2001</year>
                <number>1</number>
                <type>O</type>
                <president>ferrari</president>
            </header>
            <text>lorem ipsum ...

            </text>
        </doc>
        <doc>
            <header>
                <year>2001</year>
                <number>2</number>
                <type>O</type>
                <president>ferrari</president>
            </header>
            <text>lorem ipsum......
            </text>
        </doc>
    </full_text_docs>
</db>

这是我的xquery

xquery version "3.0";

let $doc := doc("/db//index_test/test_general.xml")//db/docs/doc
let $fulltxt := doc("/db//index_test/test_general.xml")//db/full_text_docs/doc

return <root> {
  for $a in $doc[metas/meta/details/detail[date="03/02/1993" and number = "29"]]/header
     return $fulltxt[header/year/text()=$a/year/text() and
            header/number/text()=$a/number/text() and
            header/type/text()=$a/type/text()
            ]

} </root>

基本上我只是找到匹配第一个数据库中输入的detail/numberdetail/date,并获取查询第二个数据库的结果。结果是匹配的所有<full_text_header>文档。

我想知道是否可以为字段numberdate创建索引以提高性能。请注意,这是我需要优化的唯一查询(我在此数据库上唯一做的)明显的数字和日期更改:)。

解: 要获得清晰的解释,请阅读joewiz的答案。我的问题是正确识别.xconf文件。它必须放在 / db / yourcollectiondir 中。如果您在创建文件时使用eXide,则应选择带模板&#34; eXist-db集合配置&#34;的Xml类型。当您尝试保存文件时,您会看到提示&#34; 应用配置?&#34;然后点击“确定”。然后运行此xquery xmldb:reindex('/db/yourcollectiondir')。 现在,如果在运行涉及索引的xquery时它是正确的,您将在&#34;监控和分析&#34;中找到用法。

1 个答案:

答案 0 :(得分:2)

正如该文档页面所述,eXist确实为存储在数据库中的所有XML创建了结构索引。但是,这不是值的索引,因此如果没有其他索引,基于值(而不是结构)的查询将涉及在DOM中查找值。随着数据量的增大,在DOM中查找值会越来越慢。这是基于价值的索引(例如范围索引)节省时间的地方。 (有关更全面的解释,请参阅Wolfgang Meier的"Indexing"部分&#34;调整数据库&#34;文章,这对于从eXist中获得最佳性能至关重要。)

所以,是的,您可以为<number><date>字段创建索引。我推荐&#34;新系列&#34; index,如该文档页面所述。设置这些索引的collection.xconf文件如下所示:

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

您必须将其存储在/db/system/config/集合中,并在与数据库中数据位置相对应的子集合中存储。因此,如果您的数据位于/db/apps/myapp/data,则可以将此collection.xconf文件放在/db/system/config/db/apps/myapp/data中。

请注意,此处的配置只会影响for子句对datenumber值的查询,而不会影响return子句中的谓词,这取决于<year><type>元素的值。因此,为了确保您的查询最大化索引的使用,您应该在这些上声明索引;似乎xs:integer是每种类型的合适类型。

最后,我建议删除/text()步骤,这些步骤完全无关紧要。有关text()的使用/滥用的更多信息,请参阅Evan Lenz的文章"text() is a code smell"

更新(2016-07-17):通过上面的更新代码示例,我还有一些其他建议。首先,由于代码在/db/index_test,我们将按如下方式存储我们的文件:

Contents of <code>/db/index_test</code> collection, as seen in eXide

假设您正在使用eXide,当您将collection.xconf文件存储在集合中时,eXide会提示您将该文件的副本放在/db/system/config中的正确位置。如果您不使用eXide,则需要自己存储collection.xconf文件。

使用未修改的查询,我可以确认,尽管存在collection.xconf文件,但monex显示没有应用索引:

monex showing no indexes applied

让我们对文件进行一些修改,以确保正确应用索引:

xquery version "3.0";

<root> {
    for $a in doc("/db/index_test/test_general.xml")//detail[date = "03/02/1993" and number = 29]/ancestor::doc/header
    return 
        doc("/db/index_test/test_general.xml")/db/full_text_docs/doc
            [
                header/year = $a/year and
                header/number = $a/number and
                header/type = $a/type
            ]

} </root>

通过这些修改,monex显示索引应用于for子句中的比较:

monex showing images applied

这里的见解来自&#34;调整数据库&#34;文章。要获得所有比较的完整索引,您需要定义其他索引,并可能需要对查询进行类似的修改。

最后一点:您在这些图片中看到的monex版本使用的是我本周末添加的一项功能,名为&#34; Tare&#34;,它试图从查询分析结果中过滤掉其他操作,以便帮助用户只看到自己查询的效果。此功能仍然只是一个拉取请求,因此运行当前版本,您将看不到相同的结果。