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 ...
随机推荐
- 关于关键字 volatile
关于 volatile 的使用,也是 C 语言面试的月经问题.标准答案来了: volatile is a qualifier that is applied to a variable when it ...
- libfacedetection简单使用记录
目录 1.源码下载 2.编译 2.1.linux 2.2.Windows MINGW64 2.3.VS2017 NMake编译 3.简单测试程序 3.1.测试截图 3.2.测试代码如下 1.源码下载 ...
- git变慢的原因
最近使用git更新代码变慢,进一步试了一下提交代码.执行git命令都很慢,换了idea的工作目录.更换git版本,所有操作都是徒劳. 最后关了火绒杀毒软件,才快了起来. 坑坑坑坑坑的火绒杀毒!浪费我至 ...
- 【C++】解析C++运行环境的搭建
在本篇文章中,笔者会谈谈如何搭建C++的运行环境.在不同操作系统中,运行C++编译器的命令也各不相同,最常用的编译器是GNU编译器(Linux系统)和微软Visual Studio编译器(Window ...
- 游戏开发中IIS常见支持MIME类型文件解析
游戏开发中IIS常见支持MIME类型文件解析 .apkapplication/vnd.android .ipaapplication/vnd.iphone .csbapplication/octet- ...
- Delphi XE以后的版本 程序如何瘦身
第一步:关闭debug infomation. 打开工程后,依次点击project--option--delphi compiler--linking 将右边Debug information改为Fa ...
- vue的js文件中获取vue实例
1.main.js导出vue实例: var vue = new Vue({ el: '#app', router, components: { App }, template: '<App/&g ...
- kafka调试工具kafkacat的使用
一. 安装 kafkacat 是基于kafka C语言的librdkafka库的 kafka客户端,不依赖java,小巧轻便,支持主流系统.在高版本的debain.Ubuntu下可以直接apt-get ...
- fastDFS 命令笔记
端口开放 这是命令运行的前提 iptables -I INPUT -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT iptables -I I ...
- Python3集合
集合(set)是一个无序的不重复元素序列. 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典. 创建格 ...