edgedb icon indicating copy to clipboard operation
edgedb copied to clipboard

Updating single links with linkprops don't use index for target

Open dnwpark opened this issue 3 months ago • 1 comments

Given the schema:

global N: int64;

type Target;
type Source {
    target: Target {
        lprop: int64;
    };
};

And setup:

insert Target;
with x := (
    for _ in array_unpack(array_fill(0, N))
        insert Source { target := (select Target limit 1) }
    )
select count(x);

The following query:

update Source
set {
    target := (select Target limit 1)
};

takes a nonlinear (quadratic?) amount of time:

N time (ms)
10000 7133.4
20000 30564.3
30000 75512.4

After inserting 100 more Sources,

for _ in array_unpack(array_fill(0, 100))
    insert Source { target := (select Target limit 1) };

The following query, with the new ids as $0:

for s in std::array_unpack(<array<std::uuid>>$0) union ((
    update <Source>s
    set { target := {} }
));

takes an increasing amount of time:

N time (ms)
100000 1163.2
200000 7941.1
300000 11526.2

Analyzing both queries shows the majority of time spent in ModifyTable relation_name=Source_05, possibly as a result of a HashJoin join_type=Inner.

dnwpark avatar Sep 19 '25 18:09 dnwpark

Another query which runs quite slowly is:

with __query := (
    with __all_data := <array<tuple<std::uuid,std::uuid>>>$0
    for __data in std::array_unpack(__all_data) union (
        (
            update <Source>__data.1
            set {
                target := <Target>__data.0
            }
        )
    )
)
select count(__query);

Taking a linearly increasing (quadratic?) amount of time with the number of Targets with their link set:

N time (ms)
100000 2281.4
200000 6313.9
300000 10862.5

This query appears to be slow due to a SeqScan on Source.target

dnwpark avatar Sep 22 '25 17:09 dnwpark