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 ...
随机推荐
- gdb fabs错误输出
https://sourceware.org/gdb/wiki/FAQ GDB doesn't know the return type nor the type of the arguments f ...
- Android获取通讯录并上传(包含通讯录加密)
好久没更新文章了,近期在做通讯录上传,把它分享出来,送给需要的朋友. 写了一个通讯录工具类,直接放代码吧,关键位置通过注释来解释. 这个工具类包含通讯录获取,加密,然后上传操作.看不懂的可以留言 im ...
- java中random()函数用法介绍
Random() 创建一个新的随机数生成器. 代码如下 复制代码 Random(long seed) 使用单个 long 种子创建一个新的随机数生成器. 我们可以在构造Random对象的时候指定种子 ...
- vim资源
1.http://vimcasts.org vim技巧,还有一个高达120美元的课程 目前,正在看http://vimcasts.org/blog/2013/02/habit-breaking-hab ...
- AI 名校课程&书籍 需要学习
斯坦福李飞飞-深度学习计算机视觉 http://study.163.com/course/introduction/1003223001.htm 斯坦福李飞飞-深度学习计算机视觉---视频下载 htt ...
- XSS测试代码
无script的Xss <img/src=# onerror=alert('XSS')> HTML5 XSS测试代码 <video> <source onerror=” ...
- 【资料下载区】【iCore1S相关代码、资料下载地址】更新日期2017/10/09
[iCore1S相关文档][更新中...] iCore1S原理图(PDF)下载iCore1S引脚注释(PDF)下载 [iCore1S相关例程代码][ARM][更新中...] DEMO1.0测试程序发布 ...
- webstrom IDE 激活
2017.2.27更新 选择“license server” 输入:http://idea.imsxm.com/ 2016.2.2 版本的破解方式: 安装以后,打开软件会弹出一个对话框:选择“lice ...
- Swagger UI 传入对象类型参数
Swagger要传送对象作为参数,只需添加@ModelAttribute或@RequestBody @RestController @RequestMapping("/api/json/re ...
- View - RemoteViews
设计Android的工程师起名字还是挺规范的,而且一眼就知道是什么意思.RemoteViews,顾名思义,远程的View.Android为了能让进程A显示进程B的View,设计了这么一种View(其实 ...