功能描述:做数据导出
功能分析:1.采用csv的格式,因为csv的格式比excel小
2. 3W条数据,100个字段需要全部导出
开始
直接查询
//此处使用的laravel框架,具体含义一看就懂 tableModel::orderby("id","asc")->get()->toArray();
为什么会执行这么长时间?还没有返回结果
猜测出现的问题
1.查询时间过长,mysql断开连接。
2.php内存溢出。
测试
1.先测试mysql :在Navicat 数据库工具中执行查询
mysql 执行没有什么问题。
2. 测试php是否是内存过大
echo '开始内存:'.memory_get_usage(), '</br>'; $tmp=$car_model->take(1000)->get()->toArray(); echo '运行后内存:'.memory_get_usage(), '</br>'; unset($tmp); echo '回到正常内存:'.memory_get_usage();
正常返回值了,再来2000条数据
$tmp=$car_model->take(2000)->get()->toArray();
接下来5000条
$tmp=$car_model->take(5000)->get()->toArray();
居然是原来内存的10倍,内存的占用根据条数成倍的增加,好强大。
接下来10000条数据
$tmp=$car_model->take(10000)->get()->toArray();
OH YEAH! 爆掉了
分析结果 :php内存溢出
原理:在做数据统计分析时,经常会遇到大数组,可能会发生内存溢出
ini_set(‘memory_limit’,’64M’); //重置php可以使用的内存大小为64M。
在运行到5000条查询的时候就已经60M了。所以挂了
本人的解决方案
1.利用curl多线程调用方法,避免一次性的给mysql和php 造成压力。 请看文章curl模拟多线程
2.线程数是根据数据条数来设定的,每1000条数据一个线程,3W条数据生成30个线程,每个线程生成一个csv文件。
3.文件的命名方式按照筛选条件来进行命名。文件生成后,在读取所有文件写到一个文件里面去。
后话:我开始做方案的时候,并没有具体分析问题。现在分析完问题,是内存溢出了。那我完全可以分段写入啊。
先读取1000条,写入csv文件,unset销毁变量。
在读1000条,在写入,销毁变量。
直到把数据都写进去。
测试方案行不行
echo '开始内存:'.memory_get_usage(), '</br>'; $tmp1=$car_model->take(1000)->get()->toArray(); unset($tmp1); $tmp2=$car_model->take(1000)->get()->toArray(); unset($tmp2); $tmp3=$car_model->take(1000)->get()->toArray(); unset($tmp4); $tmp4=$car_model->take(1000)->get()->toArray(); echo '运行后内存:'.memory_get_usage(), '</br>'; unset($tmp4); echo '回到正常内存:'.memory_get_usage(); die;
居然和只执行1000条内存占用是一样的
不过多线程不需要等待上一次执行完成,可能会快点,但是增加了网络传输。