Not sure if this will solve all the problems but have you looked at
the QueryBuilder?

http://jena.apache.org/documentation/extras/querybuilder/index.html

I would be interested to know how it stacks up against your
performance requirements.

Claude

On Thu, Dec 4, 2014 at 3:01 PM, Kristian Rosenvold
<[email protected]> wrote:
> We have been troubled by lots of overhead for SPARQL parsing in our
> code base, and I have been looking for something like the
> "preparedstatement" of sql with the ability to pre-interpret the
> statement and set parameters upon execution. Digging around on QA
> sites and in the code base I have come up with the following code:
>
> private static final Query q1template = .. create query with ?param
> expression...
> ...
> QuerySolutionMap params = new  QuerySolutionMap();
> params.add("param", myresource);
> QueryExecution exec = QueryExecutionFactory.create(q1template, model,params);
>
> This doubled the speed of our code, since the SPARQL parsing is pretty
> heavy and can be made a "constant" part like an sql preparedstatement.
>
> Now this does not really work, since there is mutable state in
> q1template and it can't be shared (it fails in setResultVars
> intermittently - and possibly other places too). Looking at the code
> base I see that there seem to be several potential gotchas that are
> probably lurking right under the hood, there are  too many per-request
> bits and pieces of state that are kept in the Query.
>
> Not giving up that easily, I created the following method:
>
> public static Query copyOf(Query query){
>    Query copy = new Query(query);
>    copy.setQueryPattern(query.getQueryPattern());
>    if ( query.isSelectType()) copy.setQuerySelectType();
>    else if (query.isAskType()) copy.setQueryAskType();
>    else if (query.isConstructType()) copy.setQueryConstructType();
>    else if (query.isDescribeType()) copy.setQueryDescribeType();
>
>    if (query.hasOrderBy()){
>       for (SortCondition sortCondition : query.getOrderBy()) {
>          copy.addOrderBy(sortCondition);
>       }
>    }
>    return copy;
> }
>
>
> And now I can seemingly use
>
> QueryExecution exec = QueryExecutionFactory.create(copyOf(q1template),
> model,params);
>
> and actually get this working concurrently with re-use of the parsed
> sparql expression. But of course there's ElementSubQuery pointing back
> at the Query object, so a deep copy of the queryPattern Element
> structure would probably also be required, which all seems a bit like
> barking up the wrong tree. And I'm not really sure I understand all
> the cross-references well enough to know that this would even
> work....(?)
>
> It would seem to me that the "clean" thing to do would be to separate
> the parsed sparql from the per-request state. By simple name it would
> sound like "QueryExecution" would be a nice place for these things.
> Would this work, is it a good idea ?
>
> Alternately (and much simpler), one could simply make a "reset" method
> on the Query object and accept sequential re-use. In that way I could
> use ThreadLocals to keep one instance of the query per thread and
> reduce the overall sparql parsing.
>
> I'm sort of digging a bit for suggestions/ideas here, since I'm not
> all that familiar with the code base :) We're talking about a fairly
> heavy CO2 footprint in terms of energy expenditure for repeated
> parsing of all that sparql :)
>
> (Initially I adressed this to the "users" list but I sort of changed
> my mind as the details got gorier and gorier....)
>
> Kristian



-- 
I like: Like Like - The likeliest place on the web
LinkedIn: http://www.linkedin.com/in/claudewarren

Reply via email to