阅读文档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/number
和detail/date
,并获取查询第二个数据库的结果。结果是匹配的所有<full_text_header>
文档。
我想知道是否可以为字段number
和date
创建索引以提高性能。请注意,这是我需要优化的唯一查询(我在此数据库上唯一做的)明显的数字和日期更改:)。
解:
要获得清晰的解释,请阅读joewiz的答案。我的问题是正确识别.xconf文件。它必须放在 / db / yourcollectiondir 中。如果您在创建文件时使用eXide,则应选择带模板&#34; eXist-db集合配置&#34;的Xml类型。当您尝试保存文件时,您会看到提示&#34; 应用配置?&#34;然后点击“确定”。然后运行此xquery xmldb:reindex('/db/yourcollectiondir')
。
现在,如果在运行涉及索引的xquery时它是正确的,您将在&#34;监控和分析&#34;中找到用法。
答案 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
子句对date
和number
值的查询,而不会影响return
子句中的谓词,这取决于<year>
和<type>
元素的值。因此,为了确保您的查询最大化索引的使用,您应该在这些上声明索引;似乎xs:integer
是每种类型的合适类型。
最后,我建议删除/text()
步骤,这些步骤完全无关紧要。有关text()
的使用/滥用的更多信息,请参阅Evan Lenz的文章"text() is a code smell"。
更新(2016-07-17):通过上面的更新代码示例,我还有一些其他建议。首先,由于代码在/db/index_test
,我们将按如下方式存储我们的文件:
假设您正在使用eXide,当您将collection.xconf
文件存储在集合中时,eXide会提示您将该文件的副本放在/db/system/config
中的正确位置。如果您不使用eXide,则需要自己存储collection.xconf
文件。
使用未修改的查询,我可以确认,尽管存在collection.xconf
文件,但monex显示没有应用索引:
让我们对文件进行一些修改,以确保正确应用索引:
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
子句中的比较:
这里的见解来自&#34;调整数据库&#34;文章。要获得所有比较的完整索引,您需要定义其他索引,并可能需要对查询进行类似的修改。
最后一点:您在这些图片中看到的monex版本使用的是我本周末添加的一项功能,名为&#34; Tare&#34;,它试图从查询分析结果中过滤掉其他操作,以便帮助用户只看到自己查询的效果。此功能仍然只是一个拉取请求,因此运行当前版本,您将看不到相同的结果。