Changes

Jump to navigation Jump to search
264 bytes removed ,  18:33, 1 December 2023
m
Text replacement - "<syntaxhighlight lang="xquery">" to "<pre lang='xquery'>"
Parts of the query that are static and would be executed multiple times can already be evaluated at compile time:
<syntaxhighlight pre lang="'xquery"'>
for $i in 1 to 10
return 2 * 3
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 pre lang="'xquery"'>
declare variable $INFO := true();
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 pre lang="'xquery"'>
declare function local:inc($i) { $i + 1 };
for $n in 1 to 5
Loops with few iterations are ''unrolled'' by the XQuery compiler to enable further optimizations:
<syntaxhighlight pre lang="'xquery"'>
(1 to 2) ! (. * 2)
Folds are unrolled, too:
<syntaxhighlight pre lang="'xquery"'>
let $f := function($a, $b) { $a * $b }
return fold-left(2 to 5, 1, $f)
The standard unroll limit is <code>5</code>. It can be adjusted with the {{Option|UNROLLLIMIT}} option, e.g. via a pragma:
<syntaxhighlight pre lang="'xquery"'>
(# db:unrolllimit 10 #) {
for $i in 1 to 10
In most cases, paths with a double slash can be rewritten to descendant steps…
<syntaxhighlight pre lang="'xquery"'>
(: equivalent queries, with identical syntax trees :)
doc('addressbook.xml')//city,
…unless the last step does not contain a positional predicate:
<syntaxhighlight pre lang="'xquery"'>
doc('addressbook.xml')//city[1]
</pre>
Paths may contain predicates that will be evaluated again by a later axis step. Such predicates are either shifted down or discarded:
<syntaxhighlight pre lang="'xquery"'>
(: equivalent query :)
a[b]/b[c/d]/c
Names of nodes can be specified via name tests or predicates. If names are e.g. supplied via external variables, the predicates can often be dissolved:
<syntaxhighlight pre lang="'xquery"'>
declare variable $name external := 'city';
db:get('addressbook')/descendant::*[name() = $name]
Various of these rewriting are demonstrated in the following example:
<syntaxhighlight pre lang="'xquery"'>
for $a in 1 to 10
for $b in 2
If the type of a value is known at compile time, type checks can be removed. In the example below, the static information that {{Code|$i}} will always reference items of type {{Code|xs:integer}} can be utilized to simplify the expression:
<syntaxhighlight pre lang="'xquery"'>
for $i in 1 to 5
return typeswitch($i)
If expressions can often be simplified:
<syntaxhighlight pre lang="'xquery"'>
for $a in ('a', '')
return $a[boolean(if(.) then true() else false())]
The number of elements that are found for a specific path need not be evaluated sequentially. Instead, the count can directly be retrieved from the database statistics:
<syntaxhighlight pre lang="'xquery"'>
count(/mondial/country)
The distinct values for specific names and paths can also be fetched from the database metadata, provided that the number does not exceed the maximum number of distinct values (see {{Option|MAXCATS}} for more information):
<syntaxhighlight pre lang="'xquery"'>
distinct-values(//religions)
The following queries are all equivalent. They will be rewritten to exactly the same query that will eventually access the text index of a <code>factbook.xml</code> database instance (the file included in our full distributions):
<syntaxhighlight pre lang="'xquery"'>
declare context item := db:get('factbook');
declare variable $DB := 'factbook';
Multiple element names and query strings can be supplied in a path:
<syntaxhighlight pre lang="'xquery"'>
//*[(ethnicgroups, religions)/text() = ('Jewish', 'Muslim')]
If multiple candidates for index access are found, the database statistics (if available) are consulted to choose the cheapest candidate:
<syntaxhighlight pre lang="'xquery"'>
/mondial/country
[religions = 'Muslim'] (: yields 77 results :)
If index access is possible within more complex FLWOR expressions, only the paths will be rewritten:
<syntaxhighlight pre lang="'xquery"'>
for $country in //country
where $country/ethnicgroups = 'German'
;XMark Query 1
<syntaxhighlight pre lang="'xquery"'>
let $auction := doc('xmark')
return for $b in $auction/site/people/person[@id = 'person0']
;XMark Query 8
<syntaxhighlight pre lang="'xquery"'>
let $auction := doc('xmark')
return
If sequences of items are compared against each other, a dynamic hash index will be generated, and the total number of comparisons can be significantly reduced. In the following example, <code>count($input1) * count($input2)</code> comparisons would need to be made without the intermediate index structure:
<syntaxhighlight pre lang="'xquery"'>
let $input1 := file:read-text-lines('huge1.txt')
let $input2 := file:read-text-lines('huge2.txt')
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu