mysql — Какой лучший способ сделать CSV, когда у нас есть миллионы строк в базе данных

Я работаю над проектом, в котором мне нужно извлечь миллионы строк из базы данных и создать файл CSV, но когда я пытаюсь сделать запрос, чтобы получить все строки, использование памяти растет так быстро, и приложение достигает памяти 128 МБ ограничение использования.
Я попытался разбить на строки строки базы данных, используя limit и offset, но это не сильно помогло. Есть ли решение этой проблемы?

0

Решение

я хотел бы использовать queue подход для такого рода вопросов.

Скажем, в вашей базе данных есть 100K строк. Затем вы можете создать одно задание, которое одновременно записывает 1K строк в файл CSV, и после добавления этих записей оно помещает одно и то же задание в очередь. Та же самая цепочка продолжается до тех пор, пока вы не достигнете своих 100К строк. Конечно, когда счетчик достигает 100 КБ, вам нужно убить процесс очереди.

Как будто вы следуете подходу PDO, вам нужно подождать, пока программа завершит выполнение. С моим предложенным подходом вы можете вызвать очередь один раз, и она выполнит свою работу. Вы можете сделать что-то вроде показа уведомления по электронной почте или что-то еще, когда ваш CSV будет готов.

Проведите небольшое исследование этот.

0

Другие решения

Если база данных находится в том же физическом окне, где вы запускаете этот скрипт экспорта, то:

SELECT <field list>
FROM <table>
INTO OUTFILE '/tmp/<filename>.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
1

Если вы используете mysqli_Вы можете попасть в проблемы с памятью с большим набором результатов. Это API query вызов сбрасывает весь набор результатов в память. Как вы обнаружили, ваш набор результатов не подходит.

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

  1. real_query оформить запрос.
  2. use_result начать поиск набора mysqli_result.
  3. fetch_row в цикле, чтобы получить строки по одной.
  4. свободно, когда вы закончите извлекать строки, освободите свой объект mysqli_result.

Эта проблема также возникает с другими API MySQL. В старом и устаревшем mysql API, использовать mysql_unbuffered_query вместо mysql_query,

В PDO вы должны использовать небуферизованный запрос, установив PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY в false при создании объекта запроса.

Обратите внимание, что вам также может понадобиться ограничение по времени php к высокому значению, потому что это может занять некоторое время, чтобы обработать этот набор результатов Megarow. Вы также можете сбросить его в цикле fetch_row, чтобы он не заканчивался.

Если вы используете провайдера общего хостинга, вам, вероятно, придется извлекать эти данные кусками по 50000 строк или около того, потому что провайдеры хостинга накладывают жесткие ограничения на время выполнения сценария php.

0

Никогда не храните все данные. Читайте базу данных построчно и выводите или пишите CSV после каждого.

$file = fopen('export.csv', 'w');
while($data = $query->fetch()) {
fputscsv($file, $data);
}
fclose($file);

Этот способ использует очень мало памяти.

-1