Difference between revisions of "XQuery Optimizations"

From BaseX Documentation
Jump to navigation Jump to search
(Created page with "This article is part of the XQuery Portal. It lists some optimizations that are performed by BaseX to speed up queries and reduce memory consumption. =Introduction...")
 
Line 29: Line 29:
 
==Variable Inlining==
 
==Variable Inlining==
  
The value of a variable can be ''inlined'': The variables references are replaced by the expression that is bound to the variable. The resulting expression can often be simplified:
+
The value of a variable can be ''inlined'': The variables references are replaced by the expression that is bound to the variable. The resulting expression can often be simplified, and further optimizations can be triggered:
  
 
<syntaxhighlight lang="xquery">
 
<syntaxhighlight lang="xquery">
Line 46: Line 46:
 
let $nodes := //nodes
 
let $nodes := //nodes
 
return 'Results: ' || count($nodes)
 
return 'Results: ' || count($nodes)
 +
 +
(: will be rewritten to :)
 +
let $nodes := //nodes
 +
return 'Results: ' || count(//nodes)
 +
 +
(: will be rewritten to :)
 +
'Results: ' || count(//nodes)
 +
</syntaxhighlight>
 +
 +
As the example shows, variable declarations might be located in the query prolog and in FLWOR expressions. They may also occur (and be inlined) in {{Code|try}}/{{Code|catch}}, {{Code|switch}} or {{Code|typeswitch}} expressions.
 +
 +
==Function Inlining==
 +
 +
Functions can be inlined as well. The parameters are rewitten to {{Code|let}} clauses and the function is body is bound to the {{Code|return}} clause.
 +
 +
<syntaxhighlight lang="xquery">
 +
declare function local:inc($i) { $i + 1 };
 +
for $n in 1 to 5
 +
return local:inc($n)
 +
 +
(: will be rewritten to :)
 +
for $n in 1 to 5
 +
return (
 +
  let $_ := $n
 +
  return $_ + 1
 +
)
 +
 +
(: will be rewritten to :)
 +
for $n in 1 to 5
 +
return $n + 1
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Subsequent rewritings might result in query plans that differ a lot from the original query. As this might complicate debugging, you can disable function inling during development by setting [[Option|INLINELIMIT]] to {{Code|0}}.

Revision as of 11:38, 13 July 2020

This article is part of the XQuery Portal. It lists some optimizations that are performed by BaseX to speed up queries and reduce memory consumption.

Introduction

An XQuery expression is evaluated in multiple steps:

  1. At parse time, the query string – an XQuery main module – is transformed to a tree representation, the abstract syntax tree (AST).
  2. At compile time, the syntax tree is decorated with additional information (type information, expression properties); expressions are relocated, simplified, or pre-evaluated.
  3. At evaluation time, the resulting expression tree is processed.
  4. The results are returned to the user. Some expression (such as simple loops) can be evaluated in iterative manner, whereas others (such as sort operations) need to be fully evaluated before the first result is available.

Each of the steps allows for numerous optimizations, some of which are described in this article.

If you run a query on command-line, you can use -V to output detailed query information. In the GUI, you can enable the Info View panel.

Pre-Evaluation

Parts of the query that are static and would be executed multiple times can already be evaluated at compile time:

<syntaxhighlight lang="xquery"> for $i in 1 to 10 return 2 * 3

(: will be rewritten to :) for $i in 1 to 10 return 6 </syntaxhighlight>

Variable Inlining

The value of a variable can be inlined: The variables references are replaced by the expression that is bound to the variable. The resulting expression can often be simplified, and further optimizations can be triggered:

<syntaxhighlight lang="xquery"> declare variable $INFO := true();

let $nodes := //nodes where $INFO return 'Results: ' || count($nodes)

(: will be rewritten to :) let $nodes := //nodes where true() return 'Results: ' || count($nodes)

(: will be rewritten to :) let $nodes := //nodes return 'Results: ' || count($nodes)

(: will be rewritten to :) let $nodes := //nodes return 'Results: ' || count(//nodes)

(: will be rewritten to :) 'Results: ' || count(//nodes) </syntaxhighlight>

As the example shows, variable declarations might be located in the query prolog and in FLWOR expressions. They may also occur (and be inlined) in try/catch, switch or typeswitch expressions.

Function Inlining

Functions can be inlined as well. The parameters are rewitten to let clauses and the function is body is bound to the return clause.

<syntaxhighlight lang="xquery"> declare function local:inc($i) { $i + 1 }; for $n in 1 to 5 return local:inc($n)

(: will be rewritten to :) for $n in 1 to 5 return (

 let $_ := $n
 return $_ + 1

)

(: will be rewritten to :) for $n in 1 to 5 return $n + 1 </syntaxhighlight>

Subsequent rewritings might result in query plans that differ a lot from the original query. As this might complicate debugging, you can disable function inling during development by setting INLINELIMIT to 0.