Doctrine2 ORM - 持续运行需要很长时间

时间:2014-01-24 09:49:14

标签: performance symfony orm doctrine

我有一个使用Doctrine2 ORM的Symfony2应用程序。

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

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

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

2 个答案:

答案 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秒 - 这不是快速闪电,而是更快