1

フィルタリングされた子を持つ親を返すクエリがあります。

 Context.ContextOptions.LazyLoadingEnabled = false;
  var query1 = (from p in Context.Partners
                          where p.PartnerCategory.Category == "03"
                                || p.PartnerCategory.Category == "02"
                          select new
                                     {
                                         p,
                                         m = from m in p.Milk
                                             where m.Date >= beginDate
                                                   && m.Date <= endDate
                                                   && m.MilkStorageId == milkStorageId
                                             select m,
                                         e = p.ExtraCodes,
                                         ms = from ms in p.ExtraCodes
                                              select ms.MilkStorage,
                                         mp = from mp in p.MilkPeriods
                                              where mp.Date >= beginDate
                                                    && mp.Date <= endDate
                                              select mp
                                     }).Where(
                                         p =>
                                         p.p.ExtraCodes.Select(ex => ex.MilkStorageId).Contains(
                                             milkStorageId) ).OrderBy(p => p.p.Name);
 var partners = query1.AsEnumerable().ToList();

クエリは200レコードを返し、IOrderedQueryable ToList()からの変換は非常に遅くなります。なんで?

SQL Server Management Studioでクエリをプロファイリングした後、クエリが1秒実行され、2035レコードが返されることに気付きました。

4

3 に答える 3

1

遅い理由は、それをToList実行すると、実際のクエリ実行が行われる時間だからです。これは、遅延実行と呼ばれます。

表示される場合があります:LINQと遅延実行

リストに変換するときに行う必要はないと思います。次AsEnumerableのように直接行うことができます。

var partners = query1.ToList();
于 2012-12-18T07:10:07.553 に答える
1

これには多くの理由が考えられますが、プロファイラー情報がなければ単なる推測作業であり、コードとドメインをよく知っている人による高度な教育を受けた推測作業でさえ、多くの場合間違っています。

コードをプロファイリングする必要があります。ボトルネックが DB にある可能性が高いため、@Likurg が示唆するようにコマンド テキストを取得し、DB でプロファイリングします。1 つ以上のインデックスが欠落している可能性があります。

クエリを理解しやすくし、潜在的に高速にするために他に何もなければ、クエリ自体に対してできることがいくつかあります。

例えば

p.p.ExtraCodes.Select(ex => ex.MilkStorageId).Contains(milkStorageId)

本当に

p.p.ExtraCodes.Any(ex => ex.MilkStorageId == milkStorageId)

最初の where 句に移動して、作成する匿名で型指定されたオブジェクトの数を減らすことができます最も可能性の高いケースは、比較で使用する多くのフィールドの 1 つにインデックスがなく、結果セットの各要素に対して多くのテーブル スキャンが発生する可能性があるということです。

インデックスが高速化する可能性があるフィールドのいくつかは次のとおりです。

  • ppName
  • m.日付
  • m.MilkStorageId
  • mp.Date
  • PartnerCategory.Category
于 2012-12-18T07:58:35.413 に答える
0

まず、これを使用して生成されたクエリを確認します

Context.GetCommand(query1).CommandText;

次に、dbでこのコマンドを呼び出します。そして、プロファイラーによって読み取られたレコードの数を確認します。

于 2012-12-18T07:42:41.690 に答える