#php #performance #symfony #doctrine-orm
#php #Производительность #symfony #doctrine-orm
Вопрос:
Я выполняю фильтрацию с помощью Doctrine QueryBuilder, который возвращает около 80 тыс. записей. Я выбираю только три поля (два идентификатора для двух соединенных объектов и одну строку, которая представляет собой строку длиной = 255 (никогда не бывает такой длинной, обычно около 30-40 символов). Я использую getArrayResult()
.
$filterResult = $this->getDoctrine()->getRepository('Bundle:Entity')
->createQueryBuilder('alias')
-> // selects, joins, wheres
->getArrayResult();
Я понимаю, что выполнение может занять некоторое время из-за некоторых объединений и т. Д., Но я заметил, что после выполнения и сохранения результата в переменной (массив, 80 тыс. Записей, каждая из которых представляет собой массив из 3: id / id / name) потребляемая память примерно на 70 МБ больше.
Я проверил его практически построчно, и ничего перед отправкой запроса (создание построителя запросов, обработка формы для построения фильтра) значительно увеличивает объем памяти.
Это странно, потому что, когда в другом месте я сохраняю только один столбец в простой массив с
$idsOnly = array_column($filterResult, "id"); // 80k of IDs
Это занимает около 4 МБ.
Теперь, что я пробовал (в prod
среде, конечно):
— logging
и profiling
для doctrine.dbal
значения false в config.yml
(ничего в config_prod.yml
, поэтому я предполагаю, что оно остается включенным prod
)
— $this->getDoctrine()->getConnection()->getConfiguration()->setSQLLogger(null);
в действии фильтрации контроллера вверху
— $filterResult = null;
, затем gc_collect_cycles()
— $em->clear()
и gc_collect_cycles()
практически везде, где я мог
И ничего не изменилось. С моей точки зрения, либо многомерные массивы занимают так много места, либо Doctrine оставляет некоторый мусор при извлечении результатов из БД. Что еще я должен попробовать, кроме NativeSQL?
Комментарии:
1. Просто для объявления массива, где каждая запись представляет собой массив из трех целых чисел, потребуется около 32 МБ. т.е. eval.in/654307 . Каждая переменная в PHP занимает около 144 байт;-/ Это PHP и не имеет ничего общего с Doctrine.
2. Вы правы… Но когда я перешел с QueryBuilder на raw SQL, теперь он использует половину общей памяти, что говорит о том, что Doctrine есть что мне объяснить! 🙂
3. Ну, если это всего лишь дополнительные 35 МБ, это, вероятно, понятно, doctrine добавляет дополнительный уровень, как вы знаете, выше mysql, и должен преобразовать конструктор запросов synthax в фактический запрос и (я думаю) получить фактические результаты…