-- Yes, both variants are slow.
-- Looked at the query plan, didn't find any information about indexing
The creation of database was made in the following way:
$ ./basex -Vc"SET ATTRINDEX true;SET UPDINDEX true;CREATE DB test2"
# loop, adding documents
$ ./basex -Vc"OPEN test2;CREATE INDEX ATTRIBUTE;OPTIMIZE"
Then I ran quiery, inserting attribute 'id'. No attribute 'name' was changed. But executing
for $i in index:attributes('test2', 'name')
return $i
query is still fast (and no information about indexing in query plan).
Then I tried to make the same queries for database backup before inserting attributes into nodes:
declare namespace lang = "http://s3r.ru/ns/code-language";
declare namespace t = "none";
declare variable $dbName := "test2";
declare function t:getIdByName($arg as xs:string)
{
let $x := collection($dbName)/module//object[@name = $arg]
return if( empty($x/@id) ) then "-1" else $x/@id
};
for $x in collection($dbName)/module//flow/argument/atom[@lang:tp = "function_call_name"]/@name
let $id := t:getIdByName($x)
return $id
It was slow (1958006.4ms (~30 minutes)), but in the query plan there were the lines:
Compiling:
...
- applying attribute index
...
In attachment you can find xml files I put in the collection, and this is the script for updating attributes I used:
declare namespace lang = "http://s3r.ru/ns/code-language";
declare namespace t = "none";
for $x in collection('test2')/module//object[@lang:tp = "function_body"]
return insert node (attribute { 'id' } { generate-id($x) }) into $x
..that's indeed slow. Some questions that might help:
-- did you try both queries that I sent to you?
-- did you have a look at the query plan (e.g. in the Info View), and
was the index chosen? If not, did you try to optimize your database,
or rebuild the index structures?
-- feel free to send us your test data (you may send it directly to
us); we'll have a look at it some time soon
__________________________________________
On Tue, Jun 5, 2012 at 10:17 AM, Alex Markin <alexanius@gmail.com> wrote:
> I tried to do it in this way, here is query I've run:
>
> declare namespace lang = "http://s3r.ru/ns/code-language";
> declare namespace t = "none";
>
> declare variable $dbName := "test2";
>
> declare function t:getIdByName($arg as xs:string)
>
> {
> let $x := db:attribute($dbName, $arg,
> 'name')/parent::object[ancestor::module]
> return if( empty($x/@id) ) then "-1" else $x/@id
> };
>
> for $x in collection($dbName)/module//flow/argument/atom[@lang:tp =
> "function_call_name"]/@name
> let $id := t:getIdByName($x)
> return $id
>
> The collection 'test2' contains 100 documents (it is very small collection).
> The query executed 2017156.38 ms (about 30 minutes). This is too slow :(
>
>
> 2012/6/5 Christian Grün <christian.gruen@gmail.com>
>>
>> > declare function t:getIdByName($arg)
>> > {
>> > let $x := collection($dbName)/module//object[@name = $arg]
>> > return if( empty($x/@id) ) then "-1" else $x/@id
>> > };
>>
>> Your query will be optimized if $dbName is globally declared (which I
>> guess it is anyway), and if $arg is specified as string:
>>
>> declare variable $dbName := '...';
>> declare function local:getIdByName($arg as xs:string) {
>> let $x := collection($dbName)/module//object[@name = $arg]
>> return if( empty($x/@id) ) then "-1" else $x/@id
>> };
>>
>> You may as well use db:attributes() to explicitly access the index (if
>> available):
>>
>> declare variable $dbName := '...';
>> declare function local:getIdByName($arg) {
>> let $x := db:attribute($dbName, $arg,
>> 'name')/parent::object[ancestor::module]
>> return if( empty($x/@id) ) then "-1" else $x/@id
>> };
>>
>> Hope this helps,
>> Christian
>
>