Hi,
Am 12.01.2011 12:04, schrieb William Sandri:
Anyway, regarding function testFast1, what if I use the dynamic argument I pass, like:
declare function xbpr:testFast1($objectId as xs:string?){ let $docName := $cxnDefsDocName let $conn_typeof_target := doc($docName)/CxnDefs/CxnDef[@type="RdfsType" *and @source=$objectId*]/@target return $conn_typeof_target };
wow, you are really finding all the special cases ;-).
I thought it should fall into the same situation like testSlow but it does not, it still runs fast.
It does, in the sense that the function body isn't constant and thus can't be evaluated completely. It's another optimization that saves the day here.
As $cxnDefsDocName (and by implication $docName) is a compile-time constant, the doc(...)-function can be evaluated. This makes all indices of the database available to the optimizer, resulting in this definition:
xbpr:testFast1($objectId as xs:string?) { (IndexAccess("cxn", $objectId, ATTRIBUTE)/self::source /parent::CxnDef INTERSECT IndexAccess("cxn", "RdfsType", ATTRIBUTE)/self::type /parent::CxnDef )/.[parent::CxnDefs/parent::document-node()]/@target };
That's obviously much faster than an iterative evaluation strategy.
If you're working on a limited and statically known set of documents, then it would probably be most efficient to bind all documents to static variables and then access them via those:
declare namespace xbpr = "http://www.bpeng.com/";
declare variable $amlDoc as node()* := doc("aml"); declare variable $cxnDefsDoc as node()* := doc("cxn"); (: ...the query... :)
Optimization in BaseX ist pretty complex in general and it often helps to experiment with different reformulations of the same query to help the optimizer.
I hope this clarifies it a bit, feel free to ask if anything's still unclear.
Cheers Leo