Я хотел бы использовать пакетная обработка доктрины чтобы оптимизировать вставку большого количества сущностей. Проблема в методе Clear. Это говорит о том, что этот метод отсоединяет все сущности, которыми управляет EntityManager. Итак, что я должен делать в ситуации, когда у меня есть родительский объект, у которого много детей, и у каждого ребенка есть свои дети, например:
Таким образом, у меня есть 1 поездка на сессию, 3 дорожки, и каждая дорожка имеет на время 2000 очков. Я мог бы использовать пакетную обработку в последнем цикле, который отвечает за сохранение точек. Но если я использую понятный метод, то как установить родителей для точек и треков? Чистый метод отсоединит их, верно?
Скоро у тебя будет предел памяти. Идея flush()
в партиях это нормально, но нужно clear()
EntityManager
в конце каждой партии освободить использованную память.
Но в вашем случае у вас будет ORMInvalidArgumentException
(a.k.a. «новая сущность, основанная на отношениях»), если Вы позвоните $child->setParent($parent);
после того как ты сделал $entityManager->clear();
,
Проблема в том, что $parent
сейчас в detached
состояние в UnitOfWork
, Таким образом, вы должны положить его снова в managed
государство. Это можно сделать с помощью $entityManager->merge();
или просто с помощью $parentRepository->find($parent->getId());
,
Просто убедитесь, что все сущности managed
состояние после каждого clear()
в случае, если вы собираетесь использовать их позже.
Если все ваши 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