учение и большой объем данных - PullRequest
3 голосов
/ 12 мая 2011

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

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

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

Ответы [ 3 ]

6 голосов
/ 12 мая 2011

Документация доктрины - 13. Пакетная обработка

Обновление: Для 1.2 проверьте эту страницу: http://docs.doctrine -project.org / projects /doctrine1 / en / latest / en / manual / data-hydrators.html

Под заголовком «По запросу» вы найдете ответ.

1 голос
/ 13 июля 2012

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

Мне понадобилось много времени, чтобы понять, что помогает. У меня сложилось впечатление, что пока вы остаетесь в том же 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)

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

0 голосов
/ 12 мая 2011

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

...