1

現在、処理のために大量のデータをロードする必要がある厄介で複雑なクエリがあります。データのネストはかなり深く実行されます...

public List<agZone> agZone_GetZonesWithProjectionInformation(IEnumerable<int> ids, bool includeHidden)
{
    var zones = this.BaseDB.agZones.Where(x => (includeHidden || includeHidden == x.agField.Hidden)
                                && x.agField.WeatherSourceID.HasValue
                                && x.agField.WeatherProjectionID.HasValue
                                && x.agField.SeedID.HasValue
                                && ids.Contains(x.ZoneID))
                        .Include(x => x.agField)
                        .Include(x => x.agField.agSeed)
                        .Include(x => x.agField.agSeed.agSeedCompany)
                        .Include(x => x.agField.agSeed.agSeedConfigs)
                        .Include(x => x.agField.agSeed.agSeedGrowthStages)
                        .Include(x => x.agField.agSeed.agSeedGrowthStages.Select(y => y.agGrowthStage))
                        .Include(x => x.agField.agFieldGrowthStages)
                        .Include(x => x.agField.agFarm)
                        .Include(x => x.agField.agFarm.agGrower)
                        .Include(x => x.agField.agFarm.agGrower.agUsers)
                        .Include(x => x.agZoneNitrogenApplications)
                        .Include(x => x.agZoneWaterApplications)
                        .Include(x => x.agSoilSymbol)
                        .Include(x => x.agSoilSymbol.agSoilConfigs)
                        .AsNoTracking();

    return zones.ToList();
}

これまでのところ、ここで 2 つの悪いことが起こっていることを認識しています。

  1. クエリは使用します.Contains(...)-Entity Framework 5はおそらくこれらのクエリをコンパイルまたはキャッシュできないため、毎回再生成する必要があります。それはひどいですが、私は今それを回避する方法がありません. さらに悪いことに、クエリが生成されている間、EF はクエリを待機している他のスレッドをブロックしているようです。これは本当にひどいです。
  2. インクルードを使用すると、マスターの詳細が繰り返されるため、クエリの複雑さと返されるデータの量が大幅に増加します。生成された SQL コマンドは 2100 行以上の長さで、実行計画は地獄のようなものです。

遅延読み込みするにはデータが多すぎます (それは一般的にひどいものです) zones。変数に対して複数の熱心な読み込みトリップを作成する方法がわかりません。

foreach複数のクエリを作成してから、ループや LINQを使用して自分でデータをまとめる必要がありますか? このデータをすべてメモリにロードする必要があります。そうしないと、計算がひどく実行されてしまいます。これまでのところ、これは実際に私ができる最速です。ありがとう!

4

2 に答える 2

1

別の方法として、データベースにSQL ビューを作成し、それに対して単純な EF マッピングを行うこともできます。これだけで、パフォーマンスへの影響を大幅に軽減できます。

別のテーブルまたは独自のデータ ストアに非正規化プロジェクションを作成することを検討することもできます。関連するデータが変更されるたびにその場で、またはこのデータが必要な頻度とタイムリーさに応じて、時々バッチ ジョブとして実行されます。CQRSは、この特定の問題に適している可能性があります。

于 2013-04-08T16:26:58.110 に答える