Я бы хотел использовать обработку пакетной вставки доктрины , чтобы оптимизировать вставку большого количества объектов. Проблема заключается в методе Clear. В нем говорится, что этот метод отделяет все объекты, которыми управляет EntityManager. Итак, что мне делать в ситуации, когда у меня есть родительский Entity, у которого много детей, и у каждого ребенка есть свои дети, например:
Таким образом, у меня есть 1 rideSession, 3 трека и каждый трек для isntance 2 000 очков. Я могу использовать пакетную обработку в последнем цикле, который отвечает за сохранение точек. Но если я использую чистый метод, то как установить родителей для очков и треков? Открытый метод отделит их, не так ли?
Скоро вы достигнете предела памяти. Идея flush()
в партиях в порядке, но вам нужно clear()
EntityManager
в конце каждой партии, чтобы освободить используемую память.
Но в вашем случае у вас будет ORMInvalidArgumentException
(иначе называемый «новый объект foung через отношения»), если вы $child->setParent($parent);
после того, как вы сделали $entityManager->clear();
,
Проблема в том, что $parent
теперь находится в detached
состоянии в UnitOfWork
. Поэтому вам нужно снова ввести его в managed
состояние. Это можно сделать, используя $entityManager->merge();
или просто используя $parentRepository->find($parent->getId());
,
Просто убедитесь, что после каждого clear()
в случае, если вы собираетесь использовать их позже, вы должны вернуть все Entities в managed
состояние.
Если у вас есть все 40000 объектов, которые уже загружены в память, вы можете просто использовать код без очистки. Очистка диспетчера объектов используется для оптимизации памяти в PHP-скрипте. Если у вас достаточно памяти для хранения всех объектов, которые вам не нужны, чтобы вообще удалить диспетчер объектов.
Для оптимизации памяти в этом случае вы можете unset($entity)
после каждого сохранения.
А для того, чтобы соответствовать пропускной способности БД, вы можете группировать несколько объектов, как в примере.
$batchSize = 20; for ($i = 1; $i <= 10000; ++$i) { $em->persist($entities[$i]); unset($entities[$i]); if (($i % $batchSize) === 0) { $em->flush(); } } $em->flush(); //Persist objects that did not make up an entire batch
не$batchSize = 20; for ($i = 1; $i <= 10000; ++$i) { $em->persist($entities[$i]); unset($entities[$i]); if (($i % $batchSize) === 0) { $em->flush(); } } $em->flush(); //Persist objects that did not make up an entire batch