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

时间:2023-03-09 13:04:01
php大量数据 10M数据从查询到下载 【内存溢出,查询过慢】解决方案

功能描述:做数据导出

功能分析:1.采用csv的格式,因为csv的格式比excel小

     2. 3W条数据,100个字段需要全部导出

开始

直接查询

//此处使用的laravel框架,具体含义一看就懂
tableModel::orderby("id","asc")->get()->toArray();

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

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

为什么会执行这么长时间?还没有返回结果

猜测出现的问题

1.查询时间过长,mysql断开连接。

2.php内存溢出。

测试

1.先测试mysql :在Navicat 数据库工具中执行查询

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

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

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

正常返回值了,再来2000条数据

$tmp=$car_model->take(2000)->get()->toArray();

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

接下来5000条

$tmp=$car_model->take(5000)->get()->toArray();

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

居然是原来内存的10倍,内存的占用根据条数成倍的增加,好强大。

接下来10000条数据

$tmp=$car_model->take(10000)->get()->toArray();

OH YEAH!  爆掉了

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

分析结果 :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;

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

居然和只执行1000条内存占用是一样的

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