7

それぞれ 3,500 万を超える関連レコードを含むかなり大きな関連テーブル セットがあります。パラメーター (データ範囲、型コードなど) を使用してデータベースにクエリを実行し、関連する結果セット (10 ~ 10,000 レコード) を返す WCF メソッドをいくつか作成する必要があります。

同社は EF 4.0 で標準化されていますが、4.X に対してオープンです。5.0 への移行について議論できるかもしれませんが、その可能性は低くなります。

エンティティを使用してこのような多数のレコードを処理する最善の方法は何ですか? 一連のストアド プロシージャを作成してエンティティから呼び出す必要がありますか、それともエンティティ内でできることはありますか?

データベースを制御できないため、テーブルを分割したり、マテリアライズド ビューやパーティション テーブルを作成したりすることはできません。

入力/アイデア/提案は大歓迎です。

4

3 に答える 3

8

私の仕事では、私は同様の状況に直面しました。多くのテーブルを持つデータベースがあり、それらのほとんどにはそれぞれ約 700 万から 1000 万のレコードが含まれていました。エンティティ フレームワークを使用してデータを表示しましたが、ページの表示が非常に遅いように見えました (90 ~ 100 秒など)。グリッドでの並べ替えにも時間がかかりました。最適化できるかどうかを確認するタスクが与えられました。プロファイリングした後(ANTSプロファイラー)、最適化できました(7秒未満)。

答えは「はい」です。エンティティ フレームワークは大量のレコード (数百万単位) を処理できますが、注意が必要です。

  1. データベースへの呼び出しは、実際のレコードが必要な場合にのみ行われることを理解してください。すべての操作はクエリ (SQL) を作成するために使用されるため、多数のレコードを要求するのではなく、データの一部のみをフェッチするようにしてください。フェッチサイズを可能な限りトリムする
  2. はい、すべきではありません。ストアド プロシージャを使用してモデルにインポートし、関数をインポートする必要があります。ExecuteStoreCommand()、ExecuteStoreQuery<>() を直接呼び出すこともできます。同じことが関数とビューにも当てはまりますが、EF には関数 "SELECT dbo.blah(@id)" を呼び出す非常に奇妙な方法があります。
  3. EF は、エンティティに深い階層を設定する必要がある場合、パフォーマンスが低下します。深い階層を持つエンティティには細心の注意を払ってください。
  4. レコードを要求していて、それらを変更する必要がない場合は、プロパティの変更を監視しないように EF に指示する必要があります (AutoDetectChanges)。そうすれば、レコードの取得がはるかに高速になります
  5. データベースのインデックス作成は優れていますが、EF の場合は非常に重要になります。検索と並べ替えに使用する列には、適切にインデックスを付ける必要があります。
  6. モデルが大きい場合、VS2010/VS2012 モデル デザイナーは本当に夢中になります。モデルを中規模のモデルに分割します。データベース内の同じテーブルを指している場合でも、異なるモデルのエンティティを共有できないという制限があります。
  7. 異なる場所で同じエンティティに変更を加える必要がある場合は、同じエンティティを渡して使用し、それぞれが新しい部分を取得して変更を加えて保存するのではなく、一度だけ変更を送信するようにしてください (実際のパフォーマンス向上のヒント)。
  8. 1 列または 2 列のみの情報が必要な場合は、エンティティ全体をフェッチしないようにしてください。SQLを直接実行するか、ミニエンティティを何か持つことができます。アプリケーションで頻繁に使用されるデータもキャッシュする必要がある場合があります。
  9. 取引が遅い。それらに注意してください。

これらのことを心に留めておけば、EF はプレーンな ADO.NET と同じではないにしても、ほぼ同様のパフォーマンスを提供するはずです。

于 2013-10-11T07:21:20.150 に答える
4

EF4.1 での私の経験では、最初にコードを作成します。レコードを読み取るだけでよい (つまり、レコードを書き戻さない) 場合は、コンテキストの変更追跡を有効にすることでパフォーマンスが向上します。

yourDbContext.Configuration.AutoDetectChangesEnabled = false;

これは、エンティティをロードする前に実行してください。ロードされたレコードを更新する必要がある場合は、いつでも呼び出すことができます

yourDbContext.ChangeTracker.DetectChanges();

SaveChanges() を呼び出す前に。

于 2013-01-23T19:18:37.147 に答える