1

Entity Framework 6 (SQL Server 2008 を使用) で Code First を使用している MVC 4 プロジェクトがあります。次のような特に厄介なクエリを最適化しようとしています。

var tops = Context.Top
    .Include(t => 
        t.Foo
            .Select(f => f.FooChild1
                .Select(c => c.Baz)))
    .Include(t =>
        t.Foo
            .Select(f => f.FooChild3))
    .Include(t =>
        t.Foo
            .Select(f => f.FooChild2))
    .Include(t =>
        t.Foo
            .Select(f => f.FooChild1
                .Select(c => c.Bar)))
    .Where(t => t.Foo.Count > 0)
    .ToList();

関係は次のようになります。

Top  
    1 ----> 0..N  Foo
        1 ----> 0..N  FooChild1
            1 ----> 0..N Bar
            1 ----> 0..N Baz
        1 ----> 0..N FooChild2
        0..N ----> 1 FooChild3

ご覧のとおり、クエリは大量の熱心な読み込みを行うため、結果のクエリには多くの結合が含まれます。遅延読み込みは、結果のデータで私が行っていることに対して遅すぎることが判明しました。

このために生成されたクエリは、SQL Server で実行するのに約 2 秒かかりますが、必要なデータを取得する手書きのクエリは約 91 ミリ秒しかかかりません。これを改善するために私にできることはありますか?

私が試したこと

Load()必要な他のすべてのテーブルを呼び出して、すべてのを取り除くことで、プリロードを試みましたInclude。理由はわかりませんが (このトリックは では機能しない可能性DbContextがあります)、効果はありませんでした。ナビゲーション プロパティが遅延読み込みされました。

検討していること

  1. 私が思いつく 1 つのオプションは、必要なデータを照会する SQL ビューを手書きで作成し、Code First でエンティティをそれにマップすることです。正確な方法はわかりませんが、そうすることで、生成されたクエリのパフォーマンスの低下を回避できることを願っています。

  2. データベースの設計を変更して、必要な情報がTopテーブルにキャッシュされるようにします。このオプションでデータが重複するのは好きではありませんが、少なくとも、それほど多くのナビゲーション プロパティをトラバースする必要はありません。

ポインタはありますか?

4

1 に答える 1