2012-06-06 2 views
1

Я работаю над некоторым кодом Xquery (используя SAXON) для выполнения простого файла XQuery с большим XML-файлом.XQuery Производительность Java с большим XML-файлом

Файл XML (находится в this.referenceDataPath) имеет 3 миллиона "строк" узлов и имеет вид:

<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.

Текущая скорость запроса Xquery составляет около 500 миллисекунд для каждого вызова getCount, который кажется очень медленным, учитывая, что документ XML находится в памяти, и запрос является подготовленным.

Причина, по которой я использую XQuery, является доказательством концепции будущей работы, где XML-файл будет иметь более сложный макет.

Я запускаю код на i7 с 8 ГБ оперативной памяти, поэтому память не проблема - я также увеличил выделенный размер кучи для программы.

Любые предложения о том, как я могу улучшить скорость этого кода?

Спасибо!

ответ

1

Самый очевидный ответ на вопрос, как улучшить скорость, - попробовать Saxon-EE, который имеет более мощный оптимизатор, а также использует генерацию байт-кода. Я не пробовал, но я думаю, что Saxon-EE обнаружит, что этот запрос выиграет от создания индекса, и тот же индекс будет использоваться повторно для каждого вхождения запроса.

Другим предложением, которое я бы сделал, является объявление типа переменной $ refDocument - информация о типе информации помогает оптимизатору принимать более обоснованные решения. Например, если оптимизатор знает, что $ refDocument является единственным узлом, тогда он знает, что $ refDocument // X будет автоматически находиться в порядке документа, без необходимости в операции сортировки.

Замена оператора «=» на «eq» также стоит попробовать.

1

У Zorba есть возможность проанализировать и запросить большой XML-документ. Некоторая документация об этом можно найти на http://www.zorba-xquery.com/html/entry/2012/05/31/XML_Streaming

Например, в следующем фрагменте кода мы разобрать 700мб документ через HTTP и весь процесс происходит в потоковом порядке сверху вниз:

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=

+0

Спасибо! Есть ли Java-API для Zorba, который может передавать XML-файл из локального файла, а не через HTTP? – joechip

+0

Zorba имеет API Java, но вы можете анализировать локальный файл непосредственно из XQuery. Мы сделали это для набора данных wikibooks, см. Http: //www.zorba-xquery.com/html/entry/2012/05/31/XML_Streaming – wcandillon

+0

Непонятно, почему потоковое использование должно быть преимуществом для этого варианта использования, когда многие запросы запускаются против одного документа, который может храниться в памяти. –

Смежные вопросы