18

最近、エンティティ モデルを、4.1 を使用する ObjectContext から 5.0 を使用する DbContext に移動しました。DbContextとObjectContextを使用したクエリのパフォーマンスが非常に悪いことに気付いたので、それを後悔し始めています。テストシナリオは次のとおりです。

どちらのコンテキストも、約 600 のテーブルを持つ同じデータベースを使用します。LazyLoading と ProxyCreation は両方ともオフになっています (コード例には示されていません)。どちらも事前に生成されたビューを持っています。

このテストでは、最初に 1 つの呼び出しを行い、メタデータ ワークスペースを読み込みます。次に、100 回実行される for ループで、コンテキストを新たに作成し、最初の 10 回を受け取る呼び出しを 1 回行います (これは、WCF サービスで使用されることをシミュレートするため、for ループ内でコンテキストを作成します。毎回コンテキスト)

for (int i = 0; i < 100; i++)
{
    using (MyEntities db = new MyEntities())
    {
        var a = db.MyObject.Take(10).ToList();
    } 
} 

これを ObjectContext で実行すると、約 4.5 秒かかります。DbContext を使用して実行すると、約 17 秒かかります。RedGate のパフォーマンス プロファイラーを使用して、これをプロファイリングしました。DbContext の場合、主な原因は UpdateEntitySetMappings というメソッドにあるようです。これはすべてのクエリで呼び出され、メタデータ ワークスペースを取得し、OSpace 内のすべてのアイテムを循環するように見えます。AsNoTracking は役に立ちませんでした。

編集: より詳細に説明すると、問題は実際のクエリではなく、DbSet と ObjectSet の作成\初期化に関係しています。ObjectContext で呼び出しを行うと、ObjectSet の作成に平均 42 ミリ秒かかります。DbContext で呼び出しを行うと、内部 dbset の作成に約 140 ミリ秒かかります。ObjectSet と DbSet の両方が、メタデータ ワークスペースからいくつかのエンティティ セット マッピング ルックアップを行います。私が気付いたのは、DbSet はワークスペース内のすべての型に対してそれを行うのに対し、ObjectSet はそうではないということです。テーブルの数が少ないモデルの方がパフォーマンスの差が少ないと思います (試したことはありません)。

4

3 に答える 3

4

また、コード ファースト アプローチのパフォーマンスが低いことも懸念しており、あなたと同様のシナリオでいくつかのベンチマークを実行しました。

http://netpl.blogspot.com/2013/05/yet-another-orm-micro-benchmark-part-23_15.html

DbContext は ObjectContext のラッパーであるため、単純化のためにパフォーマンスを犠牲にする必要があるため、結果は驚くべきものではありませんでした。ただし、私のテストでは次のことが示されています。

  • 取得するレコードが多いほど、違いは少なくなります
  • より多くのレコードを取得するほど、より速くしたい場合は追跡をオフにすることが重要になります

たとえば、10 レコードだけを取得する場合

ここに画像の説明を入力

コードファーストはモデルファーストよりも大幅に遅く、追跡と追跡なしの間に顕著な違いはないことに注意してください-両方の観察結果はあなたのものとまったく同じです。

ただし、10000行を取得する場合は

ここに画像の説明を入力

なお、nottracking版ではコードファーストとモデルファーストの違いはほとんどありません。また、どちらも驚くほど優れたパフォーマンスを発揮し、生の ado.net データリーダーとほぼ同じ速さです。

詳細については、私のブログ エントリに従ってください。

この単純なベンチマークは、最初にコードの性質を受け入れるのに役立ちました。poco エンティティと移行という 2 つの機能があるため、小規模なプロジェクトにはまだ適しています。一方、パフォーマンスが重要な要件であるプロジェクトでは、2 つのうちのいずれも選択しません。これは事実上、モデル ファーストのアプローチを二度と使用しないことを意味します。

(補足: 私のベンチマークは、nHibernate に何か問題があることも明らかにしています。NH を毎日使用している 2 人の独立した開発者に相談したにもかかわらず、これを説明するのを手伝ってくれる人をまだ見つけていません)

于 2013-10-01T20:06:37.130 に答える
2

DbContext は ObjectContext のラッパーです。これがあなたの質問に対する良い答えです。使いやすくするためにパフォーマンスを犠牲にした可能性があります。

于 2013-03-26T12:11:23.290 に答える
-3

私はSimple.Dataを使用して何百万ものレコードを照会していますが、非常にうまく高速に動作します。

于 2013-04-01T19:31:17.577 に答える