Laravel paginate 'Разрешенная память исчерпана' - PullRequest
0 голосов
/ 18 февраля 2020

У меня возникла проблема, когда я пытался разбить на страницы результаты большого запроса с несколькими объединениями и groupBy внутри. Часть моего кода здесь:

$lots = Lot::select('lots.id', 'lots.name', 'lots.slug', 'lots.description', 'lots.customer as lot_customer',
            'lots.created_at', 'lots.measure', 'lots.delivery_place', 'lots.amount as real_amount', 'lots.amount')
            ->leftJoin('tenders', 'tenders.id', '=', 'lots.tender_id')
            ->leftJoin('customers', 'lots.customer_id', '=', 'customers.id')
            ->groupBy('lots.id')
            ->paginate(25);

У меня было 420650 - всего записей в базе данных, но для разбивки на страницы я хотел показать только 25 записей на странице. Я получил сообщение:

Разрешен допустимый объем памяти (попытка выделить 16777224 байта) ...

Если у вас есть способ решить эту проблему, пожалуйста, поделитесь. Спасибо!

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Я обнаружил, что проблема была в том, что laravel получало общее количество записей для результатов разбивки на страницы:

public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
{
 ...
 $total = $this->toBase()->getCountForPagination()
 ...
}

protected function runPaginationCountQuery($columns = ['*'])
{
 return $this->cloneWithout($without)->cloneWithoutBindings($this->unions ? ['order'] : ['select', 'order'])->setAggregate('count', $this->withoutSelectAliases($columns))->get()->all();
}

В общем случае последний метод runPaginationCountQuery для получения количества записей создает необработанный запрос к БД, такой как:

выбор количества (*) в качестве совокупности из lots левого соединения tenders в tenders. id = lots. tender_id левого соединения customers на lots. customer_id .....

Но с groupBy в запросе вместо одна строка с общим количеством я получил 420650 строк по одному в ряду! Это был достаточно большой массив, который был создан только для подсчета количества строк, и в моем случае это была причина законченной памяти.

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

0 голосов
/ 18 февраля 2020

Вы можете увеличить предел памяти php .ini

ini_set('memory_limit','160M'); or memory_limit = 2024M
...