php – Doctrine批量插入内存使用量很大

我正在尝试使用Doctrine2和Symfony2 fixture bundle在MySQL数据库中插入大量数据(30 000行).

我看了the right way to do it.我看到很多关于内存泄漏和Doctrine的问题,但对我来说没有令人满意的答案.通常是Doctrine clear()函数.

所以,我做了各种各样的形状:

while (($data = getData()) {
    $iteration++;

    $obj = new EntityObject();
    $obj->setName('henry');
    // Fill object...

    $manager->persist($obj);

    if ($iteration % 500 == 0) {
        $manager->flush();
        $manager->clear();

        // Also tried some sort of:
        // $manager->clear($obj);   
        // $manager->detach($obj);
        // gc_collect_cycles();
    }
}

在flush()之后,PHP内存仍然很疯狂(我很确定).事实上,每次刷新实体时,内存会根据批量大小和实体而上升一定量,直到达到致命的允许内存大小耗尽错误.使用非常小的实体,它可以工作,但内存消耗增加太多:几MB而应该是KB.

clear(),detach()或调用GC似乎根本没有效果.它只清除一些KB.

我的做法有缺陷吗?我在某处错过了什么吗?这是一个错误吗?

更多信息:

>没有flush()内存几乎不动;
>降低批次不会改变结果;
>数据来自需要消毒的CSV;

编辑(部分解决方案):

@qooplmao带来了一个显着降低内存消耗的解决方案,禁用doctrine sql logger:$manager-> getConnection() – > getConfiguration() – > setSQLLogger(null);

然而,它仍然异常高并且在增加.

最佳答案
我使用this resource解决了我的问题,正如@Axalix建议的那样.

这是我修改代码的方式:

// IMPORTANT - Disable the Doctrine SQL Logger
$manager->getConnection()->getConfiguration()->setSQLLogger(null);

// SUGGESION - make getData as a generator (using yield) to to save more memory.
while ($data = getData()) {
  $iteration++;

  $obj = new EntityObject();
  $obj->setName('henry');
  // Fill object...

  $manager->persist($obj);

  // IMPORTANT - Temporary store entities (of course, must be defined first outside of the loop)
  $tempObjets[] = $obj;

  if ($iteration % 500 == 0) {
    $manager->flush();

    // IMPORTANT - clean entities
    foreach($tempObjets as $tempObject) {
      $manager->detach($tempObject);
    }

    $tempObjets = null;
    gc_enable();
    gc_collect_cycles();
  }
}

// Do not forget the last flush
$manager->flush();

最后但并非最不重要的是,当我将此脚本与Symfony数据夹具一起使用时,在命令中添加–no-debug参数也非常重要.然后内存消耗稳定.

转载注明原文:php – Doctrine批量插入内存使用量很大 - 代码日志