доктрина 2.1: использование памяти увеличилось после сброса


Мне действительно непонятно, почему после flush() память увеличивается, а не уменьшается? Я не могу найти ничего полезного в документации. Я промываю каждые 50 итераций цикла, и после каждой промывки использование памяти увеличивается на 1 МБ. При 100 промывках используется 100 МБ! Что я здесь упускаю? Я видел на веб-сайте doctrine пример с clear(), но если я его использую, я получаю исключение, что у одного из моих объектов нет набора каскадного сохранения. Может ли кто-нибудь объяснить мне, что такое сделано за кулисами, и что я должен сделать, чтобы правильно отменить все объекты доктрины?

Author: hakre, 2012-03-17

3 answers

Проблема в том, что менеджер сущностей обрабатывает все объекты. Вы должны сбросить его, если вам не нужны объекты в оперативной памяти после каждой X итераций. Попробуйте это:

// get the entity manager and save objects and flush
$em = $this->get('doctrine')->getEntityManager();
...
$em->flush();

// then reset the entity manager
$this->get('doctrine')->resetEntityManager();
 4
Author: Besnik, 2012-07-08 16:44:56

Также читайте здесь: http://docs.doctrine-project.org/en/2.0.x/reference/batch-processing.html

Он предлагает использовать $em->clear() после каждого объема операций. (что должно дать тот же эффект, что и предложил Бесник).

По ранее упомянутой ссылке:

Массовые вставки в доктрине лучше всего выполнять пакетами, используя преимущества транзакционного поведения EntityManager при записи. В следующем коде показан пример для вставка 10000 объекты с размером пакета 20. Возможно, вам придется поэкспериментировать с размером пакета, чтобы найти наиболее подходящий для вас размер. Большая партия размеры означают более подготовленное повторное использование инструкции внутри, но также означают больше работы во время промывки.

 4
Author: Rauni Lillemets, 2012-12-14 08:43:17

У меня была аналогичная ситуация с массовой вставкой записей (более 100 тыс.). Я следовал советам Рауни и Бесника и руководству Доктрины по пакетной обработке, но память все равно росла даже после $em->очистить() и resetEntityManager(). Через несколько дней я возглавил информационное уведомление о документации Доктрины:

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

И использовал необработанный SQL (MySQL) и пакетировал вставки. Использование памяти увеличилось с более чем 200 МБ с помощью Doctrine до 30 МБ с необработанным SQL. И я мог видеть, как уменьшается использование памяти, когда я извлекал элементы для вставки из исходного массива. Также намного быстрее, с 220 секунд до 20 секунд.

 0
Author: Sape The Mape, 2014-03-26 19:17:15