2012-06-06 3 views
1

큰 XML 파일에 대해 간단한 XQuery 파일을 실행하기 위해 일부 Xquery 코드 (SAXON 사용)로 작업하고 있습니다. (this.referenceDataPath에 위치)큰 XML 파일로 된 XQuery Java 성능

XML 파일은 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) 

자바 코드는 다음과 같습니다

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 파일이보다 복잡한 레이아웃을 갖는 향후 작업을위한 개념 증명입니다.

메모리가 문제가되지 않도록 i7에서 8GB RAM 코드를 실행하고 있습니다. 또한 프로그램의 할당 된 힙 크기를 늘렸습니다.

이 코드의 속도를 향상시킬 수있는 방법에 대한 제안 사항이 있으십니까?

감사합니다.

답변

1

속도를 향상시키는 방법에 대한 가장 확실한 대답은 Saxon-EE가 더 강력한 최적화 도구를 사용하고 바이트 코드 생성을 사용하는 것입니다. 나는 그것을 시도하지는 않았지만, Saxon-EE가이 쿼리가 인덱스를 구축함으로써 이익을 얻고 동일한 인덱스가 쿼리가 발생할 때마다 반복적으로 사용된다는 것을 감지 할 것이라고 생각합니다.

다른 제안은 변수 $ refDocument 유형 정보를 선언하여 옵티마이 저가보다 정보에 입각 한 결정을 내리는 데 도움이됩니다. 예를 들어, $ refDocument가 단일 노드라는 것을 옵티마이 저가 알고 있다면 정렬 작업이 필요없이 $ refDocument // X가 문서 순서대로 자동으로 인식됩니다.

"="연산자를 "eq"로 바꾸는 것도 시도해 볼 가치가 있습니다.

1

Zorba에는 큰 XML 문서를 구문 분석하고 쿼리 할 수있는 기능이 있습니다.

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를 통해 700메가바이트 문서를 구문 분석하고 전체 과정은 위에서 아래로 스트리밍 방식으로 발생, 예를 들어 http://www.zorba-xquery.com/html/entry/2012/05/31/XML_Streaming

에서 확인할 수있다 http://www.zorba-xquery.com/html/demo#CGPfEyXKvDwDfgzek/VTOIAIrJ8=

+0

감사! Zorba 용 자바 API가 HTTP가 아닌 로컬 파일에서 XML 파일로 스트리밍 할 수 있습니까? – joechip

+0

Zorba에는 Java API가 있지만 XQuery에서 직접 로컬 파일을 구문 분석 할 수 있습니다. 우리는 wikibooks 데이터 세트를 위해이 작업을 수행했습니다. http : //www.zorba-xquery를 참조하십시오.com/html/entry/2012/05/31/XML_Streaming – wcandillon

+0

메모리에서 보유 할 수있는 단일 문서에 대해 많은 쿼리를 실행하는이 사용 사례에서 스트리밍이 이점이되어야하는 이유는 분명하지 않습니다. –