具有关系的Doctrine批处理的内存使用情况

时间:2019-04-06 14:06:42

标签: php symfony doctrine-orm doctrine

TL; DR:找不到所有针对“ Doctrine ORM导入性能问题”的解决方案,因为EntityManager::clear还清除了下一批所需的实体。

我遇到了性能问题,因为在执行批处理工作时内存使用率一直在增加。我已经阅读了许多有关此问题的问题和博客文章,但是所有给定的解决方案都使用一个非常简单的示例插入实体,而没有任何集合/关系。内存限制的增加“有所帮助”,但是随着数据库的增长,我现在甚至没有物理内存。

我的导入脚本看起来像这样(非常简化的示例,用一些通用名称替换了我自己的业务逻辑):

$customers = $repo->getCustomers(); //array Customer[]
foreach ($customers as $customer) {

    // this line adds about 40kB every time
    $country = $customer->getCity()->getCountry();

    // while this doesn't add
    $city = $customer->getCity();

    // tried to use garbage collector, but even this doesn't free memory
    unset($country);
    $country = null;
    gc_collect_cycles();

    // insert logic removed for the sake of simplicity
}

当我在100个条目(手动或使用Ocramius/DoctrineBatchUtils)后添加使用EntityManager::clear()时,条目#101将失败,因为EntityManager清除了所有信息,也包括执行下一次插入操作所需的信息。因此,如果我清除EntityManager,则会出现如下错误消息:

  

[Doctrine \ ORM \ ORMInvalidArgumentException]通过关系'Invoice#customer'找到了一个新实体,该关系未配置为级联实体的持久性操作:740。解决此问题:显式调用EntityManager#persist()此未知实体或配置级联会在映射中保留此关联,例如@ManyToOne(..,cascade = {“ persist”})。

我还尝试仅清除某些实体(例如EntityManager::clear(ProductCategory::class))。我使用\Doctrine\ORM\EntityManagerInterface::getUnitOfWork来获取由Doctrine管理的所有类,并且清除一个类对已用内存没有影响,或者导致了以上错误消息(“发现新实体...”)。

如何找到所有内存的去向,以及如何改善导入逻辑以防止内存不足?

0 个答案:

没有答案