Попытка получить огромные данные [около 200 000 строк] из MySQL с помощью PHP. Получение ошибки: Неустранимая ошибка PHP: допустимый размер памяти xxxxx байт исчерпан
У меня есть приложение, которое генерирует почти 80-90 тысяч транзакций каждый месяц. Это растущее приложение, поэтому я могу ожидать, что цифры будут быстро расти. При создании ежемесячного или квартального отчета я получаю сообщение об ошибке размера памяти. Я попытался увеличить разрешенную память, и это сработало. Но я знаю, что предоставление большего объема памяти является временным решением и не является хорошей практикой в долгосрочной перспективе.
Мне нужна помощь в масштабировании этого приложения.
На мой взгляд, разбивка результата запроса на несколько управляемых фрагментов и объединение их вместе должно решить проблему.
Есть ли альтернативное/лучшее решение?
Поможет ли здесь NoSQL? как?
Редактировать:
Вот как используются данные: Таблица транзакций содержит все сведения о транзакциях, а также ссылки на основные данные, такие как идентификатор пользователя, идентификатор места/местоположения, тип транзакции.
Отчет будет:
Спасибо
В соединении/сеансе с базой данных вы можете попробовать установить "размер эффекта" на меньшее число, скажем, 1000. Если MySQL уважает это, он не будет пытаться создать весь набор результатов в памяти перед его отправкой.
Вы можете пакетировать это и добавлять выбранные строки в файл csv, вам не нужно хранить все данные в памяти и выгружать их все сразу.
Не могли бы вы использовать функции Mysql Aggregate? Они всегда должны быть быстрее, чем вытаскивать все записи и потом их обрабатывать. https://dev.mysql.com/doc/refman/8.0/en/group-by-functions-and-modifiers.html
Вставьте эту строку кода в свой скрипт вверху:
ini_set("memory_limit","128M"); // size based on your requirement if you need more than 128M then u can add this value in the place of 128M
Или другой вариант - использовать командную строку Mysql, если это возможно:
Use yourdatabasename
source mysqlfile
Генератор позволяет вам писать код, который использует foreach для перебора набора данных без необходимости построения массива в памяти, что может привести к превышению предела памяти или потребовать значительного времени обработки для генерации. Вместо этого вы можете написать функцию генератора, которая аналогична обычной функции, за исключением того, что вместо одного возврата генератор может возвращать столько раз, сколько необходимо, чтобы обеспечить значения для повторения. Например
function getRecords()
{
$sql = 'SELECT field1, field2,field3 FROM table';
$results=$db->query($sql);
while ($row = $results->fetch_assoc())) {
yield $row;
}
}
foreach ($this->getRecords() as $record) {
//process records here
}
Спасибо. Это сработало для меня. Реализованный генератор. Также разбивка набора данных на несколько управляемых фрагментов и построение отчета.
Это почти невозможно сказать, не видя, как вы используете данные; возможно, вы могли бы сделать часть обработки в sql, возможно, в php партиями и т. д.