次の疑似クエリで問題が発生しています。
var daily = from p in db.table1
group p by new
{
key1,
key2
} into g
join d in db.table2
on new { p.key1, p.key2 } equals { d.key1, d.key2 }
select new
{
col1 = g.Key.key1
col2 = g.Sum(a => a.column2)
col3 = d.column3
};
実行されますが、LINQ が SQL Server に送信する生成された SQL ステートメントはばかげています。実際の実装は、それぞれが .Sum() 計算を持つ 7 つ以上の列を使用して、上記と同様のセットアップに従います。生成された SQL には、INNER JOIN のない入れ子になった SELECT ステートメントが約 10 ~ 11 個含まれており、もちろん、実行に時間がかかります。
クエリの別の実装をテストしました。
var daily = from p in
(from p in db.table1
group p by new
{
key1,
key2
} into g
select new
{
col1 = g.Key.key1,
col2 = g.Sum(a => a.column2)
})
join d in db.table2
on new { p.key1, p.key2 } equals new { d.key1, d.key2 }
select new
{
col1 = p.col1,
col2 = p.col2,
col3 = d.column3
};
このバージョンは、単一の SUB-SELECT ステートメントと INNER JOIN ステートメントを使用して、はるかに合理的な SQL を生成します (これもほぼ瞬時に実行されます)。これについて私が嫌いなことは、最初の LINQ クエリは IMHO よりもはるかに単純で簡潔であるのに対し、2 番目のクエリは、table1 から必要なすべての列を 2 回定義する必要があるため、かなり冗長に見えることです。
これら 2 つの類似したクエリがサーバー上で非常に異なるパフォーマンスを発揮するのはなぜですか? また、コードの表現力がはるかに低いにもかかわらず、クエリ 2 のほうがはるかに効率的である理由は何ですか?
最初のクエリを 2 番目のクエリと同じくらい効率的に書き直す方法はありますか?