2016-07-13 6 views
2

文書を読むhttp://exist-db.org/exist/apps/doc/indexing.xml 「読取り」問合せのパフォーマンスを向上させる方法がわかりました(2つのパラメータ:文字列と整数)。 eXist-dbにデフォルトの構造索引がありますか? 'range index'を使って2つのparamsクエリを改善することはできますか?私のXML DBについてeXist-dbの範囲索引を使用した問合せのパフォーマンスを向上させる

詳細(単に同じルートにマージ2つの異なる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 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を見つける私のXQueryです最初のdbの入力と一致し、2番目のdbを照会するための結果を取得するdetail/dateがあります。結果は一致するすべての<full_text_header>文書です。

パフォーマンスを向上させるためにフィールドnumberdateのインデックスを作成できるかどうかを知りたいと思います。これは私が最適化するために必要な唯一のクエリです(このデータベースでは唯一のことです)明らかに数値と日付の変更:)。

解決策: 明確な説明については、joewizの回答をお読みください。私の問題は.xconfファイルの正しい認識でした。 /db/yourcollectiondirに配置する必要があります。ファイルを作成するときにeXideを使用している場合は、テンプレート "eXist-db collection configuration"でXmlタイプを選択する必要があります。ファイルを保存しようとすると、「適用設定?」と表示されます。 [OK]をクリックします。ちょうどこのxquery xmldb:reindex('/db/yourcollectiondir')を実行してください。 インデックスを含むxqueryを実行するときにすべてが適切であれば、 "モニタリングとプロファイリング"の使い方が分かります。

+0

'for'句に構文エラーがあります:2つの述語を開始し、そのうちの1つのみを終了することに注意してください。 – joewiz

+0

「collection.xconf」のようなXML文書の「New XQuery」ボタンではなく、eXideで「New」ボタンを使用することについての発見を追加してくれてありがとう。これにより、eXideは.xconfファイルをXML文書(XQueryではなく)として認識し、 '/ db/system'の適切な場所にコピーして、このインデックスをコレクションに適用できるようにします(eXideは自動的にあなたのために再インデックスを実行します;あなたはそれをやり直す必要はありません)。私は間違ったことに対してユーザーに警告するために機能リクエストをeXideに提出しました:https://github.com/wolfgangmm/eXide/issues/126。 – joewiz

答えて

2

このドキュメントのページにあるように、eXistはデータベースに格納されているすべてのXMLの構造インデックスを作成します。しかし、これは値のインデックスではありません。それ以上のインデックスがなければ、(構造ではなく)値に基づくクエリはDOMの値の検索を伴います。データが大きくなるにつれて、DOMの値を検索するのが遅くなり、遅くなります。これは、範囲索引などの値ベースの索引がその日を保存する場所です。 (より完全な説明については、ヴォルフガング・マイヤーさんはeXistの最大限のパフォーマンスを得るために不可欠であるの記事、「データベースのチューニング」の"Indexing"セクションを参照してください。)

だから、そう、あなたは<number><date>のインデックスを作成することができますフィールド。そのドキュメントのページで説明されているように、「新しい範囲」インデックスをお勧めします。これらのインデックスを設定するあなたの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値のクエリ、およびない<year><type>要素の値に依存return句で述語を、影響を与える

注意。そのため、索引の使用を最大限にするために索引を宣言する必要があります。 xs:integerがそれぞれ適切なタイプになるようです。

最後に、私は/text()のステップを排除することを提案しますが、これは完全に無関係です。 text()の使用/濫用の詳細については、Evan Lenzの記事"text() is a code smell"を参照してください。

更新(2016-07-17):上記の更新されたコードサンプルでは、​​さらに2つの提案があります。コードは/db/index_testであるので、まず、次のように、我々は我々のファイルを格納します:

あなたは、コレクション内の collection.xconfファイルを保存するとき、EXIDEを持ってするように求められます、あなたはEXIDEを使用していると仮定すると、

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

を正しい場所に置かれたファイルのコピーを/db/system/configにコピーします。 eXideを使用していない場合は、collection.xconfファイルを自分で保存する必要があります。

monex showing no indexes applied

はのは、インデックスがあることを確認するために、ファイルにいくつかの変更をしてみましょう:私はcollection.xconfファイルが存在するにもかかわらず、マネックス証券が索引には適用されませんされて表示されていることを確認することができます変更されていないクエリを使用して

正しく適用:これらの変更を加えて

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> 

、マネックスは、インデックスがfor句の比較に適用されることを示している。

monex showing images applied

ここ洞察は、「データベースのチューニング」の記事から派生しています。すべての比較に対して完全なインデックス作成を行うには、追加のインデックスを定義する必要があります。また、クエリに同様の変更を加える必要があります。

最後に、これらの写真に表示されているmonexのバージョンでは、この週末に追加した「Tare」という機能を使用しています。これはクエリのプロファイリング結果から他の操作を除外しようとします自分のクエリの効果だけ。この機能は依然としてプルリクエストであるため、現在のリリースバージョンを実行すると、同じ結果は表示されません。

+0

私はcollection.xconfステップを実行しましたが、私は 'xmldb:reindex( '/ db/mydir/mydb.xml')で再インデックスを試しました。しかし、それは "偽"を返します。再インデックスが機能しないようです。また、私は複数の異なる位置にあるタグを持っています。私は 'doc/metas/meta/details/detail/number'のインデックスを作成したいと思います。 – alfredopacino

+1

ああ、' xmldb:reindex() 'はドキュメントURIではなくコレクションURIをとります。コレクションが存在する場合、 'true()'を返します。クエリでインデックスが動作していることを確認するには、monex(監視とプロファイリング)アプリでクエリプロファイラを使用します。 – joewiz

+0

Monexの[Index usage]タブでインデックスの正しい設定を確認できません:/ – alfredopacino

関連する問題