This topic contains tips for optimizing XQuery.
declare namespace ep = "http://www.endeca.com/XQuery/pragmas/2008"; (#ep:time all#) { let $n := (#ep:time seqstuff#) { reverse(1 to 1000000)[1] } return (#ep:time add#) { $n + 1 } }which, run in exquery, emits the following:
TRACE{seqstuff}: 821.809 ms TRACE{add}: 822.199 ms TRACE{all}: 822.229 ms 1000001Not only does this imply that the all block take less time than the sum of its children, but also that creating and reversing a million-element list takes as long as performing addition. The cost of addition is actually trivial, but the XQuery compiler performed let-inlining to produce code structured like this:
declare namespace ep = "http://www.endeca.com/XQuery/pragmas/2008"; (#ep:time all#) { return (#ep:time add#) { (#ep:time seqstuff#) { reverse(1 to 1000000)[1] } + 1 } }To investigate cases where the optimizer may have interfered with the time pragma, you can put the time pragma around larger blocks of code to look out for inconsistencies, or use the !o modifier in exquery to see what the optimizer does to various kinds of expressions.
<packed> <fish>{$x/categories/foodstuffs/[@type = 'fish']}</fish> <bread>{$x/categories/foodstuffs/[@type = 'bread']}</bread> </packed>use:
let $foodstuffs := $x/categories/foodstuffs return <packed> <fish>{$foodstuffs/[@type = 'fish']}</fish> <bread>{$foodstuffs/[@type = 'bread']}</bread> </packed>This can save a significant amount of time, if $x or $x/categories or $x/categories/foodstuffs has many children. (Common sub-expression elimination has not yet been implemented.)