我想使用条理性批量插入处理,以优化大量实体的插入。问题在于清晰的方法。它说这个方法分离由EntityManager管理的所有实体。如果我有一个父实体,它有很多子实体,每个子实体都有它们的子实体,像这样:
- riseSession
- 跟踪
- 点
- 跟踪
所以我有1个骑行,3个轨道,每个轨道有2000个点。我可以在最后一个循环中使用批处理,它负责节省点数。但是如果我使用clear方法,那么如何为点和轨道设置父结点呢?Clear方法会分离它们,对吧?
很快就会达到内存限制。批量flush()
的想法是可以的,但是您需要在每个批次结束时clear()
EntityManager
以释放已使用的内存。
但在你的情况下,你将有ORMInvalidArgumentException
(又名。如果您在调用$entityManager->clear();
之后调用$child->setParent($parent);
,
问题是$parent
现在在UnitOfWork
中处于detached
状态。所以你需要再次把它放在managed
状态。这可以通过使用$entityManager->merge();
或简单地使用$parentRepository->find($parent->getId());
来完成。
只要确保在每个clear()
之后将所有实体都设置为managed
状态,以防以后使用它们
如果你已经在内存中加载了所有40000个对象,那么你可以只使用代码而不清除。清理实体管理器用于优化PHP脚本中的内存。如果你有足够的内存来存储所有的对象,你根本不需要清除实体管理器。
为了在这种情况下优化内存,您可以在每次持久化后执行unset($entity)
。
为了适应DB连接带宽,您可以将几个实体分组,如示例所示。
$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