我正在研究一些Xquery代码(使用SAXON)来执行针对大型XML文件的简单XQuery文件。
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连续多次调用(例如1000000次),以验证XML文件中许多值的存在。
对于每次调用getCount,Xquery查询的当前速度大约是500毫秒,考虑到XML文档在内存中并且查询是准备好的,这看起来非常慢。
我使用XQuery的原因是作为XML文件布局更复杂的未来工作的概念证明。
我在带有8GB RAM的i7上运行代码,因此内存不是问题 - 我还增加了程序的分配堆大小。
有关如何提高此代码速度的任何建议吗?
谢谢!
答案 0 :(得分:1)
Zorba有一个解析和查询大型XML文档的工具。 有关它的一些文档可在http://www.zorba-xquery.com/html/entry/2012/05/31/XML_Streaming
获得例如,在下面的代码片段中,我们通过HTTP解析700MB文档,整个过程从上到下以流方式进行:
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=
上试用此示例答案 1 :(得分:1)
如何提高速度的问题最明显的答案是尝试Saxon-EE,它具有更强大的优化器,并且还使用字节码生成。我没有尝试过,但我认为Saxon-EE将检测到这个查询将从构建索引中受益,并且每次出现查询时都会重复使用相同的索引。
我要做的另一个建议是声明变量$ refDocument的类型 - 类型信息有助于优化器做出更明智的决策。例如,如果优化器知道$ refDocument是单个节点,那么它知道$ refDocument // X将自动按文档顺序排列,而不需要排序操作。
用“eq”替换“=”运算符也值得尝试。