Doctrine2 ORM - 持续操作需要很长时间

问题描述 投票:0回答:2

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

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

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

有人可以提供帮助吗?

performance symfony orm doctrine
2个回答
1
投票

请参阅Doctrine 文档中的批处理。这个想法是在每个新实体上调用

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 会分离实体,循环将被 broken

如果不使用

clear()
,Doctrine2 会将所有持久化实体保留在内存中,如果它占用的内存超过 PHP 可以使用的内存,可能会导致错误。

如果您要在 Doctrine 存储库之外的其他内容上迭代循环,那么您可以在

clear()
之后调用
flush()


0
投票

感谢您的帮助。

这是我如何让它工作得更快;

创建并保留 20 个实体后,我在实体管理器上调用了lush() 和clear()。这意味着需要链接到我正在创建的实体的相关实体丢失了条令,因此需要从数据库重新加载。

现在每个实体大约需要 0.02 秒 - 这并不完全是闪电般的快,但要快得多

© www.soinside.com 2019 - 2024. All rights reserved.