php导出超大csv导出方法,读取超大文件或者接受超大数组,防止内存溢出
基本思路就是,知道总数之后分割成2万一个数组进行查询,最后独立写入csv,避免数据过大导致溢出
速度还不错,在php7下,机器I5 8G内存,128G,SSD,52W多条,大概也就30秒,出来整个文件38.2M
$per = 10000; 37秒
$per = 20000; 34秒
$per = 30000; 的时候速度最快29秒左右
$per = 40000;30-31秒
所以建议在30000步幅,比较好,我的环境是windows 32位,64位或许会更好
建议导入文件过多就zip压缩之后再下载
laravel 写的demo 2018年6月19日18:13:26
$start = time();
set_time_limit(0);
ini_set('memory_limit', '512M');
//获取总数
$count = DataChinaYearData::count();
//
$per = 30000; $section = array();
for ($i = 0; $i <= $count; $i += $per) {
$section[] = $i;
}
if (end($section) < $count) {
$section[] = $count;
}
//清理输出流的防止乱码
ob_flush();
flush();
$fp = fopen('file.csv', 'w'); foreach ($section as $k => $v) {
$list = array();
$list = DataChinaYearData::offset($v)->limit($per)->get()->toArray();
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
unset($list); //防止溢出
ob_flush();
flush();
}
fclose($fp);
$end = time(); $time = $end - $start;
echo $time . '秒';
另一种懒人写法,全部使用迭代器去操作
$start = time();
set_time_limit(0); $fp = fopen('file.csv', 'w');
foreach (new \ArrayObject(DataChinaYearData::get()->toarray()) as $k => $v) {
fputcsv($fp, $v);
}
fclose($fp);
$end = time();
$time = $end - $start;
echo $time . '秒';
原理也很简单,pdo就是迭代器,直接使用数组迭代器赋值,不使用变量接收就不会内存溢出
测试了2次,39秒和40秒,显然这样的速度就慢了一些,可以通过逻辑优化的就使用逻辑优化,纯靠语言特性优化有时候是方便了写代码但是代码思维逻辑就差多了
也可以通过使用迭代器接受超大数组,比如我需要读取一个2G或者更大的文本文件或者excel,我直接按行读取,然后全部放入迭代器中这样不会出现内存溢出的情况
伪demo,有时间在写个实际的demo
public static function test() {
pp(self::get_array() instanceof \Generator);
pp(self::get_array());
/*
* Generator Object
(
)
*
*/
foreach (self::get_array() as $k => $v) {
p($k);
p($v);
}
} public static function get_array() {
$rr = array('0' => array('a' => 'aa'), '1' => array('a' => 'bb'), '2' => array('c' => 'cc'), '3' => array('d' => 'dd'));
// $rr = array('0' => 'a', '1' => 'b', '2' => 'c', '3' => 'd'); foreach ($rr as $k => $v) {
yield $k => $v;
}
}
php导出超大csv导出方法,读取超大文件或者接受超大数组,防止内存溢出的更多相关文章
- C# oleDb方法读取Excel文件
今天学习的是从FTP上下载Excel文件,DataTable接收数据之后,在DataTable中通过筛选,删减修改之后把数据插入到DB相应表中. 优点:读取方式简单.读取速度快 缺点:除了读取过程不太 ...
- 逐行读取txt文件并存入到数组中
get_file_contents_on_line.php $file = fopen("log.txt", "r"); $user=array(); $i=0 ...
- Android studio运行时报错,方法,类找不到,或者JVM内存溢出解决方案
Error:Execution failed for task ':app:dexDebug'. > com.android.ide.common.process.ProcessExceptio ...
- java 读取本地文件并转换为byte数组
private byte[] InputStream2ByteArray(String filePath) throws IOException { InputStream in = new File ...
- POI实现大数据EXCLE导入导出,解决内存溢出问题
使用POI能够导出大数据保证内存不溢出的一个重要原因是SXSSFWorkbook生成的EXCEL为2007版本,修改EXCEL2007文件后缀为ZIP打开可以看到,每一个Sheet都是一个xml文件, ...
- Spark Scala 读取GBK文件的方法
1. 在生产环境下,很多文件是GBK编码格式的,而SPARK 常用的textFile方法默认是写死了读UTF-8格式的文件,其他格式文件会显示乱码 用如下代码实现读取GBK文件的方法 import o ...
- java 读取TXT文件的方法
java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...
- java读取TXT文件的方法
java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...
- Java关于读取Excel文件~xlsx xls csv txt 格式文件~持续汇总~
所需的jar百度网盘链接:https://pan.baidu.com/s/146mrCImkZVvi1CJ5KoiEhQ提取码:c329 1 需要导入jar包,缺1不可 dom4j-1.6.1.jar ...
随机推荐
- ionic中android的返回键
ionic中android的返回键 在ionic框架中已经注册了几个返回事件,分别是 view sideMenu modal actionSheet popup loading 他们的优先级分别是 v ...
- springboot-admin自定义事件通知
springboot-admin组建已经提供了很多开箱即用的通知器(例如邮件),但在有些业务场景下我们需要做一些企业内部的通知渠道,这就需要我们来自定义通知器. 实现其实很简单,只需要往spring注 ...
- 全栈JavaScript之路(十九)HTML5 插入 html标记 ( 一 )innerHTML 与outerHTML
在须要给文档插入大量的html 标记下.通过DOM操作非常麻烦,你不仅要创建一系列的节点,并且还要小心地依照顺序把它们接结起来. 利用html 标签 插入技术,能够直接插入html代码字符串,简单.高 ...
- <转>SQL Server CROSS APPLY and OUTER APPLY
Problem SQL Server 2005 introduced the APPLY operator, which is like a join clause and it allows joi ...
- Kettle实现数据抽取、转换、装入和加载数据-数据转移ETL工具
原文地址:http://www.xue51.com/soft/5341.html Kettle是来自国外的一款开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,绿色无需 ...
- mysql查询前几条记录
#My SQL 取前多少条select * from table LIMIT 5,10; #返回第6-15行数据 select * from table LIMIT 5; #返回前5行 select ...
- centos6 利用外部的smpt服务器计划任务发送邮件
centos可通过修改配置文件以使用外部SMTP服务器,达到不使用sendmail而用外部的smtp服务器发送邮件的目的, 操作如下: 一.安装mailx与sendmail # yum -y inst ...
- 【原创 Hadoop&Spark 动手实践 9】Spark SQL 程序设计基础与动手实践(上)
[原创 Hadoop&Spark 动手实践 9]SparkSQL程序设计基础与动手实践(上) 目标: 1. 理解Spark SQL最基础的原理 2. 可以使用Spark SQL完成一些简单的数 ...
- (转)java术语(PO/POJO/VO/BO/DAO/DTO)
转自:http://blog.csdn.net/gaoyunpeng/article/details/2093211 PO(persistant object) 持久对象在o/r 映射的时候出现的概念 ...
- Ubuntu安装cuda
到官网选择对应的cuda版本.cuda跟显卡的驱动是有个依赖关系的.参见这篇博客 然后按照提示,运行按照程序 sudo sh cuda_10..130_410.48_linux.run 然后安装完成后 ...