0
votes

I've got a BaseX XML database with ~20 XML files. These files are different in size and structure. The biggest file has got 524 MB. It consists of a parent ARTICLE tag with 267685 ART subtags.

This is my XQuery: "/ARTICLE/ART[PRDNO=12345]" (pretty straightforward; proper namespaces omitted for clarity). PRDNO is a foreign key to the PRODUCT/PRD XML structure, there are multiple (in average ~10) products per article.

Everything works as it is supposed to, but this query is quite slow - it takes approximately 1s to execute. Similar queries for other objects in the database (where the data amount is smaller) are much faster.

What can I do to optimize this query?

I ran "optimize" (which took some minutes), I ensured the TEXT index is in place.

This is the output of "info database":

> info database
Database Properties
 Name: hospindex
 Size: 1740 MB
 Nodes: 69360063
 Documents: 22
 Binaries: 0
 Timestamp: 2014-09-03-09-34-07

Resource Properties
 Timestamp: 2014-09-03-09-21-14
 Encoding: UTF-8
 CHOP: true

Indexes
 Up-to-date: true
 TEXTINDEX: true
 ATTRINDEX: true
 FTINDEX: false
 LANGUAGE: English
 STEMMING: false
 CASESENS: false
 DIACRITICS: false
 STOPWORDS:
 UPDINDEX: false
 MAXCATS: 100
 MAXLEN: 96

EDIT: This is the query execution plan:

Compiling:
- adding text() step
Query:
/*:ARTICLE/*:ART[*:PRDNO=1005935]
Optimized Query:
(db:open-pre("hospindex",0), db:open-pre("hospindex",32884731), ...)/*:ARTICLE/*:ART[(*:PRDNO/text() = 1005935)]
Result:
- Hit(s): 1 Item
- Updated: 0 Items
- Printed: 2078 Bytes
- Read Locking: local [hospindex]
- Write Locking: none
Timing:
- Parsing: 1.12 ms
- Compiling: 0.46 ms
- Evaluating: 1684.35 ms
- Printing: 0.35 ms
- Total Time: 1686.3 ms
Query plan:
<QueryPlan>
  <IterPath>
    <DBNodeSeq size="22">
      <DBNode name="hospindex" pre="0"/>
      <DBNode name="hospindex" pre="32884731"/>
      <DBNode name="hospindex" pre="33685448"/>
      <DBNode name="hospindex" pre="38260847"/>
      <DBNode name="hospindex" pre="38358876"/>
    </DBNodeSeq>
    <IterStep axis="child" test="*:ARTICLE"/>
    <IterStep axis="child" test="*:ART">
      <CmpG op="=">
        <CachedPath>
          <IterStep axis="child" test="*:PRDNO"/>
          <IterStep axis="child" test="text()"/>
        </CachedPath>
        <Int value="1005935" type="xs:integer"/>
      </CmpG>
    </IterStep>
  </IterPath>
</QueryPlan>
1
Well, I could use another XML database, or even a relational database; but I like BaseX because of its simplicity and would like to stick to it.Matthias Wuttke
The attribute index is activated, that should be ok. Could you also dump the query plan? It is always displayed in the GUI, and can be activated using the QUERYINFO option in the command line.Jens Erat

1 Answers

4
votes

Your query will be evaluated much faster when using quotes around your search value:

/ARTICLE/ART[PRDNO = "12345"]

The reason is that the current version of BaseX does not provide a numeric value index (it may be included in BaseX 8.0).

You get more insight into the query compilation steps by turning on the QUERYINFO option.