私は、低速のレガシーデータベースから最大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でも可能であれば。
誰か考えがありますか?