31

現在、foreach ループでエンティティを作成または更新する必要がある場所にいます。

だから私は次のことをしています(短いコード):

foreach ($dataset as $data) {
    $entity = new Entity();

    // ---- Some setting operations on the entity

    $em->persist($entity);
}

$em->flush();

私が期待していたのは、Doctrine がエンティティを管理し、1 つのステートメントでエンティティをテーブルに挿入することです。

しかし、Doctrine は、作成されたエンティティごとに 1 つのステートメントを作成します。$dataset 配列は非常に大きくなる可能性があるため (多くのエンティティが作成される)、1 つのステートメントにまとめたいと思います。

どうすればこれを達成できますか?

4

3 に答える 3

22

Doctrine のドキュメントによると、挿入はバッチで実行するのが最適です。そして、 @AlterPHP の回答の開発です。

使用できます:

$batchSize = 20;

for ($i = 1; $i <= 10000; ++$i) {

    $car = new Car();
    // ... set number of wheels, but should always be to 4 right ?

    $em->persist($car);

    if (($i % $batchSize) === 0) {
        $em->flush();
        $em->clear(Car::class); // Detaches all Car objects from Doctrine!
    }
}

$em->flush(); // Persist objects that did not make up an entire batch
$em->clear(Car::class);

PS: Doctrine 13.1から読んだところです。一括挿入セクション。必要なのは、より大きな駐車場だけです。

于 2015-05-08T15:23:24.187 に答える
19

greg0ireによって提案されているように、このリンクは Doctrine が INSERT ステートメントを最適化する方法を説明しています:スライド #47)。トランザクションを使用しますが、一意のステートメントで同じオブジェクトの INSERT をグループ化しません。

一度に DB サーバーに渡すデータの量を本当に分割する必要がある場合は、x ステートメントごとに EntityManager::flush() を処理することをお勧めします。

于 2012-04-17T14:20:50.890 に答える
4

このコードを変更します。

foreach ($dataset as $data) {
    $entity = new Entity();
    // ---- Some setting operations on the entity
    $em->persist($entity);
}

に:

foreach ($dataset as $data) {
    $entity = new Entity();
    // ---- Some setting operations on the entity
    $em->persist($entity);
    $em->flush();
    $em->clear();
}
于 2012-06-06T02:04:58.527 に答える