Доктрина 2 обновление большой партии - PullRequest
0 голосов
/ 07 сентября 2018

Я использую Symfony 3.4 и Doctrine. Мне нужно обновить большое количество сущностей (300k +), используя Doctrine. Я прочитал блочную статью из Doctrine-документов и прочитал темы из стека, но проблема в том, что несмотря на размер пакета (20, 100, 200, 500), я все равно получаю ошибку «недостаточно памяти», когда я приближается к 20 тыс. обработанных объектов.

Вот моя функция.

Может кто-нибудь, пожалуйста, дать мне подсказку / предложение, как этого избежать?

protected function execute(InputInterface $input, OutputInterface $output): void
{
    $io          = new SymfonyStyle($input, $output);
    $em          = $this->getContainer()->get('doctrine.orm.entity_manager');
    $em->getConfiguration()->setSQLLogger(null);

    $repository  = $em->getRepository('AppBundle:Order');
    $qb          = $repository->createQueryBuilder('o');

    $totalCount = (int) $qb->select($qb->expr()->count('o'))
        ->where($qb->expr()->eq('o.amountOut', 0))
        ->getQuery()
        ->getSingleScalarResult();
    $progressBar = $io->createProgressBar($totalCount);

    $query       = $qb->select('o')
        ->where($qb->expr()->eq('o.amountOut', 0))
        ->getQuery();
    $iterableResult = $query->iterate();

    $batchSize = 100;
    $i         = 0;

    foreach ($iterableResult as $row) {
        /** @var Order $order */
        $order          = $row[0];
        $commissionsArr = $this->calcCommissionInOutFromOrder($order);
        $amountOut      = $order->getTransferAmount();

        $order->setAmountOut($amountOut);
        $order->setCommissionIn($commissionsArr['commission_in']);
        $order->setCommissionOut($commissionsArr['commission_out']);
        $em->persist($order);

        $progressBar->advance();

        if (0 === ($i % $batchSize)) {
            $em->flush();
            $em->clear();
        }

        ++$i;
    }
    $em->flush();

    $io->success('Suckess');
}

1 Ответ

0 голосов
/ 10 сентября 2018

Найден фактический ответ в Утечка памяти при выполнении запроса Doctrine в цикле .

Цитата: «Я решил эту проблему, добавив - no-debug к моей команде. Оказывается, что в режиме отладки профилировщик хранил информацию о каждом запросе в памяти.»

Это действительно сработало. Используя memory_get_usage () я проверил это.

...