Doctrine2 $em-> persist ($ entity) в цикле foreach
Я сейчас нахожусь в месте, где мне нужно создать или обновить объекты в цикле foreach.
Итак, я делаю следующее (короткий код):
foreach ($dataset as $data) {
$entity = new Entity();
// ---- Some setting operations on the entity
$em->persist($entity);
}
$em->flush();
Я ожидал, что Doctrine управляет сущностями, а затем с одним утверждением вставляет сущности в таблицу.
Но происходит, что Doctrine делает один оператор для каждого созданного объекта.
Поскольку массив $dataset может быть довольно большим (создано множество объектов), я хотел бы, чтобы он был упакован в один оператор.
Как я могу это достичь?
Ответы
Ответ 1
Как было предложено greg0ire, эта ссылка описывает, как Doctrine оптимизирует инструкции INSERT: http://www.slideshare.net/jwage/doctrine-2-not-the-same-old-php-orm (см. слайд # 47). Он использует транзакции, но не группирует INSERT из тех же объектов в уникальном выражении.
Если вам действительно нужно разделить объем данных, которые вы передаете на сервер БД сразу, я предлагаю вам обрабатывать EntityManager:: flush() каждый оператор x.
Ответ 2
В документации 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(); // Detaches all objects from Doctrine!
}
}
$em->flush(); // Persist objects that did not make up an entire batch
$em->clear();
PS: я просто прочитал, что из Doctrine 13.1. Раздел "Массовые вставки" . Теперь вам понадобится большая парковка!
Ответ 3
Измените этот код:
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();
}