2

symfony/doctrine で 90000 以上のレジスタを一括挿入するインポート モジュールを実行しています。各オブジェクトを挿入するには、他のテーブルからフィールドを読み取る必要があります。したがって、レジスタごとに、次のように、まず他のテーブルから関連するオブジェクトを取得します。

$this->doctrine->getRepository('table1')

書きたい新しいオブジェクトに入れてから、次のように書きます。

$em = $this->doctrine->getManager();
$em->merge($newObject);
$em->flush();

(既存のオブジェクトと新しいオブジェクトの両方を保存する一般的な方法であるため、マージを使用します)しかし、Apacheを長時間待機させても(これは望ましくありません)、時間がかかりすぎて応答がタイムアウトします。Doctrine_Collection メソッドも機能しません。これをより適切に行う方法を知っている人はいますか?

ありがとう

4

1 に答える 1

3

Doctrine は、すべてのマネージド エンティティ インスタンスをアイデンティティ マップ ( UnitOfWork) 内に保持します。これは、永続化されるようにスケジュールされているエンティティ ( flush()) がメモリに保持されることを意味します。膨大な数の挿入を実行している場合、これはパフォーマンス キラーになる可能性があります。

逆に、インスタンスを 1 つだけ永続化/保存し、毎回フラッシュを呼び出すと、INSERT/UPDATEエンティティごとに少なくとも 1 つのインスタンスが発生します。これも、不要なデータベース クエリのためにパフォーマンスに影響します。

必要な挿入を小さなチャンクに分割し、エンティティ マネージャーがメモリ内インスタンスを解放できるようにすることを検討する必要があります。

foreach($entities as $index => $entity) {
  $entity->setFoo('bar'); 
  $objectManager->merge($entity);

  if (($index % 1000) == 0) {
    $entityManager->flush(); // Flush the changes every 1000 iterations
    $entityManager->clear(); // Clear all managed entities
  }
}

あなたDoctrine_Collectionが言及したことは実際に適用さDoctrine 1れ、それ以来多くが変更されました。

詳細については、バッチ処理に関する Doctrine 2のドキュメントを参照してください。

于 2013-11-04T13:20:51.147 に答える