Доктрина и большой объем данных

У меня есть запрос, который возвращает ~ 50k строк, похоже, что доктрина положила весь этот результат в память, что превышает ограничение памяти (128M) единственное решение, которое я нашел, которое сохраняет некоторую память, -

$result->execute(array(), Doctrine_Core::HYDRATE_NONE);

но он все же превышает предел, есть ли способ читать одну строку за раз с учением?

Ответы

Ответ 2

Пакетная обработка помогает!

Мне понадобилось много времени, чтобы выяснить, что помогает. У меня такое впечатление, что пока вы остаетесь в одном и том же php-процессе, вы не можете освободить свою память. Так что это не помогло мне:

  • $object- > бесплатно (правда)
  • снята с охраны ($ объекта)
  • sfConfig:: set ('sf_debug', false)
  • gc_collect_cycles()/gc_enable()
  • Doctrine_Core:: HYDRATE_ON_DEMAND
  • sfCommandApplicationTask:: runTask()
  • sfDoctrinePager

Что действительно помогло подсказка от Rich Sage, которая предложила порождать подпроцессы для выполнения Части работы. Предел и смещение для запроса задаются в качестве параметров между процессами. Чтобы получить строку за строкой, установите $options['limit'] в 1, но 50 также должно быть хорошим значением:

daddyTask.class.php

[..]
$total = ItemTable::getInstance()->createQuery('i')->count();

for ($offset = 0; $offset < $total; $offset += $options['limit'] )
{
    passthru(
        sprintf('%s %s/symfony doTask --limit=%s --offset=%s', sfToolkit::getPhpCli(), sfConfig::get('sf_root_dir'), $options["limit"], $offset),
        $returnVar
    );
 }

doTask.class.php

$items = ItemTable::getInstance()->createQuery('i')->limit($options['limit'])->offset($options['offset'])->execute();

foreach( $items as $item )
{
    // ..do something with the item
    $this->log( 'INFO: '.memory_get_peak_usage(true).' memory in use.' );
}

(Я использую Doctrine 1.2 в платформе Symfony 1.4 на PHP 5.3.10)

Любые комментарии или критика по этой теме очень ценятся, поскольку для меня это сложно!

Ответ 3

есть ли причина, по которой вы не используете → limit() и → offset()?