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 つのオプションは、必要なデータを照会する SQL ビューを手書きで作成し、Code First でエンティティをそれにマップすることです。正確な方法はわかりませんが、そうすることで、生成されたクエリのパフォーマンスの低下を回避できることを願っています。
データベースの設計を変更して、必要な情報が
Top
テーブルにキャッシュされるようにします。このオプションでデータが重複するのは好きではありませんが、少なくとも、それほど多くのナビゲーション プロパティをトラバースする必要はありません。
ポインタはありますか?