php 导出大量数据到数据表
大数据量一般方式导出存在哪些问题?
需要导出的数据一般都是从数据库中读取,然后执行导出操作。
一般方式导出(数据量少的方式导出)是先一次性从数据读取所需的数据,然后执行一次性导出操作。
百万级大数据量如果按这种方式导出,主要会遇到哪些问题呢?
执行时间长,很容易超时
服务器内存不够,百万级的数据从数据库一次性读取消耗的内存会导致服务器内存溢出,从而导致导出失败
导出的excel文件比较大,且excel有行数限制
如何解决执行时间长,很容易超时问题
set_time_limit (0); //取消脚本运行时间的限制
如何解决服务器内存不足问题
百万级的数据从数据库一次性读取改为分页读取,采用fputcsv,使用output流, 渐进式的往output流中写入数据, 写到一定量后将系统缓冲冲刷到响应中(增量导出)
导出的excel文件比较大及excel导出行数限制问题
csv相比于excel文件有其一定的优势:
一般xls的格式最大支持六万行的数据左右,csv格式文件对数据的行数没有限制,而且csv文件占用空间比excel文件小。
在国外科学数据网站下载的CSV文件有几十G上百G,行数多大几十亿上百亿行;
但是Excel、wps、openoffice紧支持打开编辑前面1048576行;snapde软件支持的行数多一些,一次可以打开编辑一两千万行的CSV数据,速度很快。
set_time_limit(0);//取消脚本运行时间的限制 ini_set('memory_limit', '1024M');//设置内存限制 $columns = [ '列名1', '列名2', '列名3' //需要几列,定义好列名 ]; //设置好告诉浏览器要下载csv文件的headers $fileName = 'test'; header("Content-Disposition: attachment; filename=\"" . $fileName . ".csv\""); header('Content-Type:APPLICATION/OCTET-STREAM'); $fp = fopen('php://output', 'a');//打开output流 mb_convert_variables('GBK', 'UTF-8', $columns);//解决中文乱码问题 fputcsv($fp, $columns);//将数据格式化为CSV格式并写入到output流中
//添加查询条件,获取需要的数据 $query = Model::class()->where(); //获取总数,分页循环处理 $accessNum = $query->count(); $perSize = 1000; $pages = ceil($accessNum / $perSize); //分页读取,避免一次读取造成内存不足 for($i = 1; $i <= $pages; $i++) { $db_data = $query->limit($perSize)->offset(($i-1)*$perSize)->select(); foreach($db_data as $key => $value) { $rowData = []; //获取每列数据,转换处理成需要导出的数据 //需要格式转换,否则会乱码 mb_convert_variables('GBK', 'UTF-8', $rowData); fputcsv($fp, $rowData); } //释放变量的内存 unset($db_data); //【注意:每处理完一页,刷新输出缓冲到浏览器】 ob_flush(); //必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。 flush(); } fclose($fp); exit();

浙公网安备 33010602011771号