php导出csv性能问题,如何通过PHP将数百万行从MySQL导出到CSV而不会耗尽内存?

博客作者遇到了在PHP中导出数百万行MySQL数据到CSV文件时内存耗尽的问题。他们尝试了两种方法:一次性获取所有数据和分批获取,但都导致内存不足。作者考虑使用MySQL的命令行导出,但管理层对此持保留态度。他们询问是否有其他可行的PHP解决方案来处理大规模数据导出。
摘要由CSDN通过智能技术生成

所以我有这张桌子:

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读取.

第一次尝试

我试图提出一个巨大的请求,一次选择所有(as per this blog post),但这有,尽管使用 – > iterate(),导致允许内存大小1073741824字节运行~9s后耗尽.

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);

第二次尝试

我检索了总行数,然后做了一个循环,使得相同数量的查询逐个检索行.但是在向.csv文件写入~260K行之后,PHP耗尽了内存并抛出了与上面相同的错误:允许的内存大小为1073741824字节.

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);

第三次尝试

我曾想过使用exec()函数来运行导出表的MySQL命令行.但是,我的经理似乎不喜欢这个选项.

所以我自欺欺人地认为使用PHP将〜9.5M的行转储到.csv文件中甚至可能吗?还有其他我还没知道的方法吗?

感谢您对此的帮助.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值