2014-01-24 30 views
2

我有一个使用Doctrine2 ORM的Symfony2应用程序。Doctrine2 ORM - 需要很长时间的持久性操作

我想从XML文件创建实体,然后坚持实体。典型的XML文件可能包含需要保持的几千条记录。 XML中的每条记录都不会直接映射到单个实体上,而是映射到实体上,然后映射到一对多关系“多”端的其他实体。

我可以从XML元素创建实体,但它涉及在实体上运行“持久化”,每个操作在我的机器上需要大约2秒。从XML文件导入数千条记录,这对我们的需求来说太慢了。

任何人都可以提供任何帮助吗?

+0

这是工作的方式是建立在一个阵列被保留和储存所有实体。一旦XML文件被读取,它就会遍历数组,并在每个实体上运行“持久化”。然后它称为“冲洗”。我现在意识到这不是最好的方法。它应该在创建时保留每个实体,然后定期刷新。 –

回答

0

请参阅Batch Processing in Doctrine documentation。想法是在每个新实体上调用persist(),但只有在一组n实体持续存在后才使用flush()。对于每个实体来说,花费的时间要少于拨打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存储库以外的内容进行迭代,则可以在flush()之后调用clear()

0

感谢您的帮助。

以下是我如何更快地工作;

在创建并保存了20个实体后,我在实体管理器上调用了flush()和clear()。这就意味着需要链接到我创建的实体的相关实体已经失去了教条,所以需要从数据库中重新加载。

现在需要为每个实体周围0.02秒 - 这不正是闪电快,但要快得多