9

私は、低速のレガシーデータベースから最大800,000レコード(レコードフェッチ時間あたり1.4〜2ミリ秒...合計)をMySQLにダンプするバッチプロセスに取り組んでいます。これにより、パフォーマンスが少し速くなります。これを最適化するために、私はすべてのMySQLレコードをメモリにロードしており、使用量は約200MBになります。次に、レガシーデータベースからのダンプとレコードの更新を開始します。

元々、これでレコードの更新が完了すると、SaveContextを呼び出して、メモリを約500MB〜800MBから1.5GBにジャンプさせます。すぐに、メモリ不足の例外が発生し(これが実行されている仮想マシンには2GBのRAMがあります)、RAMを増やしても、1.5〜2GBはまだ少し過剰であり、それはバンドを置くだけです。 -問題を支援します。これを修正するために、10,000レコードごとにSaveContextを呼び出し始めました。これは、少しでも役に立ちました。デリゲートを使用してレガシーデータベースからデータをフェッチし、MySQLで更新していたので、パフォーマンスにそれほどひどい打撃は受けませんでした。保存中に5秒ほど待機すると、バックアップされた3000程度のレコードのメモリ内の更新が実行されます。ただし、メモリ使用量は増え続けます。

これが私の潜在的な問題です:

  • データはレガシーデータベースから任意の順序で出力されるため、更新をチャンクして定期的にObjectContextを解放することはできません。
  • 事前にMySQLからすべてのデータを取得せず、代わりに更新プロセス中にレコードで検索すると、非常に遅くなります。代わりに、事前にすべてを取得し、主キーでインデックス付けされたディクショナリにキャストし、データを更新するときにディクショナリからレコードを削除します。

私が考えた解決策の1つは、エンティティによって使用されているメモリをなんらかの方法で解放することです。エンティティは既に更新されているため(キャッシュをクリアするなど、特定のアイテムに対してのみ)、二度と触れることはありませんが、わかりません。それがEntityFrameworkでも可能であれば。

誰か考えがありますか?

4

2 に答える 2

6

コンテキストでDetachメソッドを呼び出して、不要になったオブジェクトを渡すことができます。http: //msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.detach%28v=vs.90% 29.aspx

于 2012-06-29T01:15:04.803 に答える
2

あなたの最善の策は、以前に提案されたような別のツールではないのか、それともEntityFrameworkの使用をやめただけなのか疑問に思います。代わりに、ORMなしでコードを実行する場合は、次のことができます。

  1. SQLステートメントを調整して、パフォーマンスを向上させます
  2. トランザクションの範囲を簡単に制御および変更して、最高のパフォーマンスを実現します。
  3. 一度に1つずつ実行するのではなく、サーバーを呼び出して複数の更新を実行しないように、更新をバッチ処理できます。
于 2012-06-29T02:08:55.803 に答える