LiveLinq Query Performance: logical optimization
Standard LINQ to Objects does not perform any logical optimization, it executes queries exactly as they are written. And, of course, standard LINQ to Object does not use indexes for optimization. In comparison, LiveLinq performs physical optimization (using indexes, if they are present) and logical optimization (re-writing the query in a more efficient form before processing it).
However, LiveLinq does not contain a full-scale query optimizer like one in a relational database such as SQL Server or Oracle, so it can still matter how a query is written. But it is largely limited to join ordering. LiveLinq does not try to re-order your joins. Joins are executed always in the same order as specified in the query. So, you should avoid writing queries with obviously inefficient join order. But it must be noted that it is a relatively rare problem (and the same consideration, of course, applies to the standard LINQ to Objects anyway). It can be an issue in a query like
from a in A
join b in B on a.k equals b.k (1)
where b.p == 1
if there are, for example, only 10 elements in B with b.p == 1 and only 100 elements in A that satisfy a.k == b.k and b.p == 1, but the overall number of elements in A is many times higher, for example, 10000. Then the query above will require 10000 "cycles", whereas rewritten with the right join order,
from b in B
join a in A on b.k equals a.k (2)
where b.p == 1
this query will require only 100 cycles to complete. Note that the position of where is not important. The above query has the same performance as
from b in B
where b.p == 1 (3)
join a in A on b.k equals a.k
That's because of LiveLinq query optimization: LiveLinq re-writes (2) internally to (3) when it executes it, because it is preferable to check conditions before performing other operations and to exclude elements that don't contribute to the result. This is one of the logical optimizations performed by LiveLinq internally.