DataSource for Entity Framework for WPF/Silverlight
LiveLinq クエリーパフォーマンス:論理的な最適化
DataSource for Entity Framework > プログラミングガイド > LiveLinq クエリーパフォーマンス:論理的な最適化

標準の LINQ to Objects は、論理的な最適化を実行せず、クエリーを記述されたとおりに正確に実行します。当然、標準の LINQ to Object は、最適化のためにインデックスを使用することもありません。対照的に、LiveLinq は、物理的な最適化(インデックスがあればインデックスを使用する)と論理的な最適化(実行前にクエリーを効率的な形式に書き換える)を行います。

LiveLinq には、SQL Server や Oracle などのリレーショナルデータベースに含まれているような、完全なクエリーオプティマイザは含まれていません。このため、クエリーがどのように記述されているかが引き続き問題となる場合があります。ただし、これは主に結合順序に限られます。LiveLinq は、結合を並べ替えることはしません。結合は、常に、クエリーで指定された順序で実行されます。このため、明らかに非効率的な結合順序でクエリーを記述しないようにする必要があります。ただし、これは比較的珍しい問題であること(そして、同じ問題が標準の LINQ to Objects にも当然当てはまること)に注意してください。次のようなクエリーでは、結合の順序が問題になることがあります。

LINQ
コードのコピー
from a in A
join b in B on a.k equals b.k                        (1)
where b.p == 1

たとえば、b.p == 1 となる要素が B に 10 個しかなく、a.k == b.k かつ b.p == 1 を満たす要素が A に 100 個しかないが、A の要素の総数がその何倍にもなる(10000 個など)場合です。その場合、上のクエリーには 10000 "サイクル" が必要です。一方、次のように正しい結合順序でクエリーを書き直すと、

LINQ
コードのコピー
from b in B
join a in Aon b.k equals a.k                         (2)
where b.p == 1

このクエリーの実行には 100 サイクルしか必要になりません。where の位置は重要ではないことに注意してください。上のクエリーのパフォーマンスは、次のクエリーと同じです。

LINQ
コードのコピー
from b in B
where b.p == 1                                        (3)
join a in A on b.k equals a.k

これは、LiveLinq によってクエリーが最適化されるためです。つまり、LiveLinq は、実行時に内部で(2)を(3)に書き換えます。これは、他の操作を実行する前に条件をチェックして、結果に影響しない要素を除外した方がよいからです。この処理は、LiveLinq によって内部的に実行される論理的な最適化の1つです。