教义2批量插入/更新存储器(Doctrine 2 bulk insert/update memory

2019-11-02 21:45发布

考虑下面的代码(包裹函数内使用):

    $manager = $this->manager; // local ref
    $q = $manager->createQuery('select c from VendorFeedBundle:Category c');
    $iterableResult = $q->iterate();
    $i = 0;
    $batchSize = 500;

    foreach($iterableResult as $row) {
        $category = $row[0];

        $struct = explode(' ' . $this->separator . ' ', $category->getPath());
        unset($struct[count($struct) - 1]);
        $path = implode(' ' . $this->separator . ' ', $struct);

        if (!$parent = $this->repo->findOneBy(['path' => $path])) {
            continue;
        }

        $category->setParent($parent);

        // flush every x entities
        if (($i % $batchSize) == 0) {
            echo 'Flushing batch...' . "\n";
            echo 'Memory: ' . $this->getReadableSize(memory_get_usage()) . "\n";

            $manager->flush();
            $manager->clear();

            echo 'After batch...' . "\n";
            echo 'Memory: ' . $this->getReadableSize(memory_get_usage()) . "\n";
        }
        ++$i;
    }

    // flush the remaining
    $manager->flush();
    $manager->clear();

它记录在我的终端如下:

Creating tree...
Memory: 14.91 MB
Flushing batch...
Memory: 18.46 MB
After batch...
Memory: 18.79 MB
Flushing batch...
Memory: 21.01 MB
After batch...
Memory: 23.29 MB
Flushing batch...
Memory: 25.36 MB
After batch...
Memory: 27.87 MB
Flushing batch...
Memory: 29.88 MB
.... etc

该getReadAbleSize方法不泄漏到全局范围或任何东西任何变量。 我已阅读并随后咨询有关doctrine2批量插入/更新(批处理): http://docs.doctrine-project.org/en/latest/reference/batch-processing.html

我究竟做错了什么? 每500个项目3〜4 MB的内存增加似乎是一个(小)泄漏给我。

旁注:我需要的,因为我的系统是在2个进程分裂更新项目这种方式; 首先我插入的类别,其次我更新父关系。

我的类别类是基本Doctrin2实体加入到它(树,意译,timestampable)几Gedmo扩展名请参见: http://pastie.org/private/oiiyf54zjuouhiqjsjislg

我完整的脚本(这是迭代和更新类别): http://pastie.org/private/k5x240vr4taepczhqa4tva

Answer 1:

  1. 设置SQL记录为空

$em->getConnection()->getConfiguration()->setSQLLogger(null);

  1. 手动调用函数gc_collect_cycles()之后$em->clear()

$em->clear(); gc_collect_cycles();

不要忘记设置zend.enable_gc 1,或手动调用gc_enable()之前使用gc_collect_cycles()

  1. 添加--no-debug ,如果你从控制台运行命令选项。


文章来源: Doctrine 2 bulk insert/update memory