Open mikhail-khalizev opened 4 years ago
@mikhail-khalizev In LiteDB, only one index can be used per query. All other filter expressions are evaluated after the results are retrieved, even if the expression uses indexes fields. If there are multiple clauses eligible for indexed search, the query execution pipeline tries to select the one that will give the best performance. In this scenario, it probably evaluates both clauses equally, and always ends up selecting the first one (the left clause).
I ran a slightly modified version of your test: I converted the Linq expressions to Bson expressions and also added a third query that uses the expression $._id between @0 and @1
(which is not available through Linq expressions).
What I noticed is that queries that use only Limit
perform better when Id >= low
is the index expression, and the reverse is true for queries that use only Offset
. And the query that uses between
outperformed both by a significant margin – which is to be expected, given that its filter is executed at once (index mode: INDEX RANGE SCAN(_id BETWEEN 24900 AND 25100)
).
Wow. Then I suggest make optimization - if LiteDb meets Where(x => x.Id >= low && x.Id <= high)
it replace it to between
.
Also it possible optimize
Where(x => x.Id > low && x.Id < high)
as
($._id between @0 and @1
and $._id > low
and $._id < high
).
Version 5.0.8
Describe the bug It's not really bug. But suggestion for query optimization. In code below I start 2 equivalent queries. In first condition is
Where(x => x.Id >= low && x.Id <= high)
. In second condition flips:Where(x => x.Id <= high && x.Id >= low)
.But time of execution those queries differ in 2 times!
Code to Reproduce
Expected behavior I expect that time of queries execution to be no more than 5% different.
Additional context
Test Output: