Более быстрое сохранение и очистка для импорта доктрины mongodb odm

Я использую symfony2 и doctrine mongodb odm для импорта данных о товарах из файлов CSV. Я создал консольную команду, чтобы создать объекты Product, а затем сохранить их и сбросить DocumentManager. Промывка занимает более 30 секунд, а у меня всего пара тысяч продуктов. В будущем их будет гораздо больше.

Мне интересно, есть ли какие-либо оптимизации / лучшие практики, чтобы ускорить очистку большого количества новых объектов в доктрине. Похоже, что не нужно было бы так много обрабатывать объекты, поскольку все они новые и их просто нужно добавить в коллекцию.


person MDrollette    schedule 30.08.2012    source источник
comment
Вы промываете пару тысяч продуктов за один прием или после каждого приема?   -  person Florent    schedule 30.08.2012
comment
Вы уверены, что проблема в операции сброса, а не в обработке до нее? Вы его сравнивали?   -  person Florent    schedule 30.08.2012
comment
Я сделал, синтаксический анализ CSV, создание объектов и сохранение занимает 1-2 секунды. вызов сброса в конце занимает более 30 секунд.   -  person MDrollette    schedule 30.08.2012
comment
Возможно, вы могли бы включить ведение журнала и профилирование Doctrine. Обязательно проделайте то же самое с MongoDB. Не думаю, что проблема в обработке PHP ...   -  person Florent    schedule 30.08.2012
comment
прости, я идиот. был включен профилировщик xdebug. все еще требуется 7 секунд, чтобы смыть его, но я полагаю, что это более разумно?   -  person MDrollette    schedule 30.08.2012
comment
Да, 7 секунд - это разумно, чтобы сохранить более 2.000 записей с прибора.   -  person Florent    schedule 30.08.2012


Ответы (2)


У меня возникла аналогичная проблема (загрузка тысяч товаров из CSV как бы). Моя проблема больше связана с нехваткой памяти, но решение также показало значительное увеличение скорости.

По сути, я помещал счетчик в цикл и сбрасывал диспетчер, а затем очищал его время от времени. Я обнаружил, что размер партии 150 дает наилучшие результаты. Я уверен, что это во многом зависело от того, как вы их обрабатываете, поскольку у меня было ОЧЕНЬ много обработки чисел, чтобы очистить данные перед их вставкой.

Для справки, он загружает около 5500 продуктов с более чем 100 полями и обрабатывает их примерно за 20 секунд. До модификации требовалось 3+ минуты (если она вообще закончилась из-за нехватки памяти).

//LOOP  {
   if ($count % $batchSize == 0) {
      $manager->flush();
      $manager->clear();
      gc_collect_cycles();
      if ($count % $batchSize == 0)
         echo $count . ' | ' . number_format((memory_get_usage() / 1024), 4) . " KBs\n";
   }
$count++;
}

Не забудьте запустить $ manager-> flush () хотя бы еще раз после завершения цикла, чтобы поймать те записи 1–149, которые не запускают его в цикле.

person Wpigott    schedule 26.12.2012
comment
+1 за последний кончик смыва после петли. Я потратил 2 часа, пытаясь исправить тест, из-за которого не получал обновленный результат;) - person Gui; 30.04.2014

У меня очень большая база данных. Я считаю, что гораздо эффективнее выполнять промывку каждый раз, когда вы вставляете код, для лучшего управления доступом к базе данных.

$dm->persist($object);
$dm->flush();
$dm->clear();
person vinzcoco    schedule 03.07.2013
comment
Это, вероятно, приведет к увеличению накладных расходов и усугубит проблему скорости, так как полные вычисления UOW должны будут выполняться после каждой записи. - person Wpigott; 15.03.2015