Как экспортировать миллионы строк из MySQL в CSV через PHP без исчерпания памяти?

Поэтому у меня есть эта таблица:

mysql> DESCRIBE table; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(15) unsigned | NO | PRI | NULL | auto_increment | | unid | char(9) | NO | UNI | NULL | | | rs | varchar(255) | NO | | NULL | | +-------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) 

Что содержит миллионы строк:

 mysql> SELECT COUNT(1) FROM table; +----------+ | COUNT(1) | +----------+ | 9435361 | +----------+ 1 row in set (0.00 sec) 

Я хочу экспортировать все строки в .csv файл (я использую Symfony2.6 ). Этот файл предназначен для хранения на сервере (не загружен), а затем, прочитанного PHP.

1-я попытка

Я попытался сделать огромный запрос, чтобы выбрать все сразу ( в соответствии с этим сообщением в блоге ), но это, несмотря на использование ->iterate() , привело к Allowed memory size of 1073741824 bytes exhausted после запуска за ~ 9 секунд.

  ini_set('memory_limit', '1024M'); ini_set('max_execution_time', -1); $results = $em ->getRepository('MyBundle:Entity') ->createQueryBuilder('e') ->getQuery() ->iterate(); $handle = fopen('/path/to/csv/file/', 'w'); while (false !== ($row = $results->next())) { fputcsv($handle, $row[0]->toArray()); $em->detach($row[0]); } fclose($handle); 

Вторая попытка

Я получил общее количество строк, а затем сделал цикл для того, чтобы одно и то же число запросов получало строки по одному. Но после того, как написано ~ 260 тыс. Строк в .csv файл, у PHP закончилась нехватка памяти и выдается такая же ошибка, как указано выше: Allowed memory size of 1073741824 bytes exhausted .

  ini_set('memory_limit', '1024M'); ini_set('max_execution_time', -1); $total = (int) $em ->getRepository('MyBundle:Entity') ->countAll(); $csv = '/path/to/csv/file'; $handle = fopen($csv, 'w'); for($i = 1; $i < $total; $i++) { $entity = $em->getRepository('MyBundle:Entity')->findOneById($i); fputcsv($handle, $entity->toArray()); $em->detach($entity); } fclose($handle); 

3-я попытка

Я подумал об использовании функции exec() для запуска командной строки MySQL, которая будет экспортировать таблицу. Однако моему менеджеру, похоже, не нравится этот вариант.


Так что я обманываю себя, думая, что демпинг ~ 9,5M строк с использованием PHP в .csv файл даже возможен? Есть ли другой способ, о котором я еще не знаю?

Спасибо за вашу помощь в этом.

Related of "Как экспортировать миллионы строк из MySQL в CSV через PHP без исчерпания памяти?"

Вместо того, чтобы пытаться построить дерево объектов, вы можете прямо попытаться выбрать результат в файл: http://dev.mysql.com/doc/refman/5.7/en/select.html

Что-то вроде

 SELECT * INTO OUTFILE "c:/temp/mycsv.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM theTable; 

Это должно оставить работу до mysql и обойти ограничения любой памяти php.


Как отметил venca: в этом случае пользователю, под которым вы используете службу mysql, необходимо написать разрешения для соответствующего каталога.