Hi Marco,
In BaseX, during the compilation phase, we try to find out if a path expression can be rewritten for index access. In your first query, the name of the database is directly specified as argument of the collection function, which makes it (relatively) obvious. In the second query, it will be passed on via the map expression (... ! ...). It would be possible to optimize the second query as well – and maybe we will do so in a future version of BaseX – but usually, the map expression is used if more than one argument is to be passed on to the next expressions.
And if I got you right, this is exactly what you would like to do here. This would mean that we would need to statically check for all possible inputs if databases with up-to-date index structures exist, and if the query can be rewritten for index access. Cases like this may lead to a large number of different possible query plans, and the time for precompiling the queries may evn outweigh the costs for accessing the data sequentially.
Another option would be to always generate several query plans for different execution strategies (with and without index) and to dynamically choose the best exeuction strategy at runtime, depending of the properties of the currently accessed database. Once again, this would be an interesting optimization, but the number of promising query plans can soon grow exponentially for a more complex query.
The straightforward solution is to access the index directly [1] if you know that it exists beforehand:
for $db in ('db1', 'db2') let $a := db:attribute($db, '2015000000016940', 'id') return $a/parent::*:item
[1] http://docs.basex.org/wiki/Db_Module#db:attribute
In our use case we'd like to have a list of dbs to query on and the list can grow over time so we would not like to change the code by replicating the queries every time a db is added. What is the way out? Thanks, Marco.