php大量数据 10M数据从查询到下载 【内存溢出,查询过慢】解决方案

功能描述:做数据导出

功能分析: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条内存占用是一样的

不过多线程不需要等待上一次执行完成,可能会快点,但是增加了网络传输。

原文地址:https://www.cnblogs.com/zhaoyang-1989/p/7007825.html