我有一个使用Doctrine2 ORM的Symfony2应用程序。
我正在尝试从XML文件创建实体,然后保留实体。典型的XML文件可能包含需要保留的几千条记录。 XML中的每条记录都不会直接映射到单个实体上,而是映射到实体上,然后映射到一对多关系“很多”一侧的其他实体。
我可以从XML元素创建实体,但它在实体上运行“persist”,每个操作在我的机器上花费大约2秒。从XML文件中导入了数千条记录,这对我们的需求来说太慢了。
有人可以提供任何帮助吗?
答案 0 :(得分:1)
见Batch Processing in Doctrine documentation。我们的想法是在每个新实体上调用persist()
,但只有在持久保存一组flush()
个实体后才使用n
。与为每个实体调用persist()
然后flush()
相比,花费的时间更少。
例如:
$batchSize = 20;
for ($i = 1; $i <= 10000; ++$i) {
$user = new CmsUser;
$user->setStatus('user');
$user->setUsername('user' . $i);
$user->setName('Mr.Smith-' . $i);
$em->persist($user);
if (($i % $batchSize) === 0) {
$em->flush();
}
}
我删除了clear()
,因为它会分离所有实体。例如,如果您使用带有实体的foreach() {}
,则会出现问题,因为Doctrine2将分离实体,循环将已损坏。
不使用clear()
,Doctrine2会将所有持久化实体保留在内存中,如果内存占用的内存超过PHP可以使用,则会导致错误。
如果您在Doctrine存储库之外的其他内容上迭代循环,那么您可以在clear()
之后调用flush()
。
答案 1 :(得分:0)
感谢您的帮助。
以下是我如何让它更快地运作;
在创建并保留了20个实体之后,我在实体管理器上调用了flush()和clear()。这意味着需要链接到我正在创建的实体的相关实体丢失了原则,因此需要从数据库重新加载。
现在每个实体需要大约0.02秒 - 这不是快速闪电,而是更快