1

大きな XML ファイルに対して単純な XQuery ファイルを実行するために、いくつかの Xquery コード (SAXON を使用) に取り組んでいます。

XML ファイル (this.referenceDataPath にあります) には 300 万の「行」ノードがあり、次の形式になっています。

<row>
<ISRC_NUMBER>1234567890</ISRC_NUMBER>
</row>
<row>
<ISRC_NUMBER>1234567891</ISRC_NUMBER>
</row>
<row>
<ISRC_NUMBER>1234567892</ISRC_NUMBER>
</row>

等...

XQuery ドキュメント (this.xqueryPath にあります) は次のとおりです。

declare variable $isrc as xs:string external;
declare variable $refDocument external;
let $isrcNode:=$refDocument//row[ISRC_NUMBER=$isrc]
return count($isrcNode)

Java コードは次のとおりです。

private XQItem referenceDataItem;
private XQPreparedExpression xPrepExec;
private XQConnection conn;

//set connection string and xquery file
this.conn = new SaxonXQDataSource().getConnection();
InputStream queryFromFile = new FileInputStream(this.xqueryPath);

//Set the prepared expression 
InputStream is  = new FileInputStream(this.referenceDataPath);
this.referenceDataItem = conn.createItemFromDocument(is, null, null);
this.xPrepExec = conn.prepareExpression(queryFromFile);
xPrepExec.bindItem(new QName("refDocument"), this.referenceDataItem);   

//the code below is in a seperate method and called multiple times
public int getCount(String searchVal){

    xPrepExec.bindString(new QName("isrc"), searchVal, conn.createAtomicType   (XQItemType.XQBASETYPE_STRING));

    XQSequence resultsFromFile = xPrepExec.executeQuery();
    int count = Integer.parseInt(resultsFromFile.getSequenceAsString(new Properties()));
    return count;

}

メソッド getCount は、XML ファイル内の多くの値の存在を検証するために、連続して何度も呼び出されます (たとえば、1000000 回)。

Xquery クエリの現在の速度は、getCount の呼び出しごとに約 500 ミリ秒です。これは、XML ドキュメントがメモリ内にあり、クエリが準備されたものであることを考えると、非常に遅いようです。

私が XQuery を使用している理由は、XML ファイルがより複雑なレイアウトを持つ将来の作業の概念実証としてです。

8GB RAM を搭載した i7 でコードを実行しているため、メモリは問題になりません。また、プログラムに割り当てられたヒープ サイズも増やしました。

このコードの速度を改善する方法について何か提案はありますか?

ありがとう!

4

2 に答える 2

1

速度を向上させる方法に関する質問に対する最も明白な答えは、より強力なオプティマイザーを備え、バイトコード生成も使用するSaxon-EEを試すことです。試したことはありませんが、Saxon-EEは、このクエリがインデックスを作成することでメリットがあることを検出し、クエリが発生するたびに同じインデックスが繰り返し使用されると思います。

私が行うもう1つの提案は、変数$ refDocumentの型を宣言することです。型情報は、オプティマイザーがより多くの情報に基づいた決定を行うのに役立ちます。たとえば、オプティマイザが$ refDocumentが単一ノードであることを知っている場合、ソート操作を必要とせずに、$ refDocument//Xが自動的にドキュメントの順序になることを知っています。

「=」演算子を「eq」に置き換えることも試してみる価値があります。

于 2012-06-09T23:51:25.980 に答える
1

Zorba には、大きな XML ドキュメントを解析およびクエリする機能があります。これに関するいくつかのドキュメントは、http://www.zorba-xquery.com/html/entry/2012/05/31/XML_Streamingで入手できます。

たとえば、次のコード スニペットでは、HTTP 経由で 700 MB のドキュメントを解析し、完全なプロセスが上から下へのストリーミング方式で行われます。

import module namespace http = "http://expath.org/ns/http-client";
import module namespace p = "http://www.zorba-xquery.com/modules/xml";
import schema namespace opt = "http://www.zorba-xquery.com/modules/xml-options";

let $raw-data as xs:string := http:send-request(<http:request href="http://cf.zorba-xquery.com.s3.amazonaws.com/forecasts.xml" method="GET" override-media-type="text/plain" />)[2]
let $data := p:parse($raw-data, <opt:options><opt:parse-external-parsed-entity opt:skip-root-nodes="1"/></opt:options>)
return
    subsequence($data, 1, 2) 

この例をhttp://www.zorba-xquery.com/html/demo#CGPfEyXKvDwDfgzek/VTOIAIrJ8=でライブで試すことができます。

于 2012-06-06T19:51:16.327 に答える