Извлекайте огромные данные из MySQL

Попытка получить огромные данные [около 200 000 строк] из MySQL с помощью PHP. Получение ошибки: Неустранимая ошибка PHP: допустимый размер памяти xxxxx байт исчерпан

У меня есть приложение, которое генерирует почти 80-90 тысяч транзакций каждый месяц. Это растущее приложение, поэтому я могу ожидать, что цифры будут быстро расти. При создании ежемесячного или квартального отчета я получаю сообщение об ошибке размера памяти. Я попытался увеличить разрешенную память, и это сработало. Но я знаю, что предоставление большего объема памяти является временным решением и не является хорошей практикой в ​​​​долгосрочной перспективе.

Мне нужна помощь в масштабировании этого приложения.

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

Есть ли альтернативное/лучшее решение?

Поможет ли здесь NoSQL? как?

Редактировать:

Вот как используются данные: Таблица транзакций содержит все сведения о транзакциях, а также ссылки на основные данные, такие как идентификатор пользователя, идентификатор места/местоположения, тип транзакции.

Отчет будет:

  • Вытащить записи из таблицы транзакций
  • Замените основные ссылки соответствующим образом [замените идентификатор пользователя именем, адресом и т. д.]
  • Дамп данных в формате csv/xls
  • Сохранить/скачать файл

Спасибо

Это почти невозможно сказать, не видя, как вы используете данные; возможно, вы могли бы сделать часть обработки в sql, возможно, в php партиями и т. д.

jeroen 28.05.2019 14:12

В соединении/сеансе с базой данных вы можете попробовать установить "размер эффекта" на меньшее число, скажем, 1000. Если MySQL уважает это, он не будет пытаться создать весь набор результатов в памяти перед его отправкой.

The Impaler 28.05.2019 14:28

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

Eakethet 28.05.2019 14:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
240
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Не могли бы вы использовать функции 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
}

Спасибо. Это сработало для меня. Реализованный генератор. Также разбивка набора данных на несколько управляемых фрагментов и построение отчета.

GBhat 03.06.2019 09:19

Другие вопросы по теме