原则2 $em->持久($entity) on foreach 循环



我目前在一个地方,我需要在foreach循环中创建或更新实体。

所以我正在做以下事情(短代码):

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

我所期望的是 Doctrine 管理实体,然后用一个语句将实体插入表中。

但碰巧的是,教义对每个被创造的实体都做了一个陈述。由于$dataset数组可能非常大(创建了很多实体),因此我想将其打包到一个语句中。

我怎样才能做到这一点?

从 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:我刚刚从教义 13.1 中读到了这一点。批量插入部分。现在你所需要的只是一个更大的停车场!

正如greg0ire所建议的,这个链接描述了Doctrine如何优化INSERT语句:https://www.slideshare.net/jwage/doctrine-2-not-the-same-old-php-orm/47-sflive2010_Insert_Performance_Inserting_20(从幻灯片#47看)。它使用事务,但不将相同对象的 INSERT 分组到唯一语句中。

如果你真的需要一次划分你传递给数据库服务器的数据量,我建议你每 x 语句处理一次 EntityManager::flush()。

更改此代码:

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();
}

相关内容

最新更新