注意的问题点:


1、Excel

Excel2003版最大行数是65535行,Excel2007版的行数(1048576行)才能达到我们的要求,所以我们需要使用Excel的版本必须为2007版及以上,所以想几百万条轻轻松松一次性导入一张EXCEL表是不行的,你起码需要进行数据分割,保证数据不能超过104W一张表,PHPexcel内存溢出:既然数据限制在104W,那么就数据分割,于是你尝试50W一次导入表,然而PHPexcel内部有函数报内存溢出错误,然后你就不断的调小数据量,直到5W一次导入你都会发现有内存溢出错误。这是为什么呢,虽然你分割数据来导入多个数据表,但是最后PHPexcel内部还是一次性把所有表数据放进一个变量中来创建文件……额,这几百万数据一个变量存储,你想内存不溢出,还真有点困难。
(PHPExcel也有解决方案,PHPExcel_Settings::setCacheStorageMethod方法更改缓冲方式来减小内存的使用)


2、超时问题


脚本允许运行的时间,一般默认为30秒,如果超过了此设置,脚本返回一个致命的错误。
方法一
在php.ini可以通过定义max_execution_time来设置PHP页面的最大执行时间。
方法二
在脚本中添加set_time_limit(0);
这个函数指定了当前所在php脚本的最大执行时间,假设为800秒,实际上 最大执行时间=php.ini里的max_execution_time数值 - 当前脚本已经执行的时间 + 设定值
假如php.ini里的max_execution_time=30,当前脚本已经执行5秒,则:
最大执行时间=30-5+800=825秒。
括号里边的数字是执行时间,如果为零说明永久执行直到程序结束,如果为大于零的数字,则不管程序是否执行完成,到了设定的秒数,程序结束。
注意:这个函数的运行需要你关闭安全模式,在php.ini中将safe_mode = Off 安全模式设置为Off,否则将会出现错误


3、内存溢出问题


php默认内存限制是128M,如果一次性的把所有数据从数据库取出填充到内存中,一下不光内存存储不够,并且如果服务器CPU配置不高的话使用率一下也能达到100%,会造成服务器卡负载。可以从两个方向解决:
一 配置方向,解决方法:
方法一  直接在程序中添加代码:
ini_set('memory_limit', '1024M')。
方法二  修改php.ini配置文件
查找到memory_limit = 128M这一行,将128M改大点。
重启服务器。
方法三  修改 .htaccess
php_value memory_limit XXX M ;

注意: php内存溢出时,memory_limit设置太大会影响系统速度,因为系统和数据库及其他程序同样需要内存空间,一般系统和数据库内存空间是自己分配的
二  代码中用yield生成器(从PHP 5.5开始引入的)来处理内存溢出。具体可以参考一篇大神的文章 PHP百万级数据导出方案(生成器直接输出单个CSV)


4、缓存(buffer)过多


PHP也有自己的buffer机制。默认是开启的,大小默认4096(4kb),在php.ini配置文件中由output_buffering配置。当执行php执行echo,print的时候,是先将数据写入php的buffer,当一个php buffer写满的时候,脚本进程会将php 的buffer数据发送给系统内核交由tcp传给浏览器显示,数据流程:
echo/pring -> php buffer -> tcp buffer (服务器系统buffer)-> 浏览器 buffer ->浏览器展示

当你用PHP原生函数putcsv()其实就使用到了输出缓存buffer,如果你把几百万的数据一直用这个函数输出,会导致输出缓存太大而报错的,因此我们每隔一定量的时候,必须进行将输出缓存中的内容取出来,设置为等待输出状态。可以在代码中添加:

ob_flush();  //把数据从PHP的缓冲(buffer)中释放出来
flush();       //把不在缓冲(buffer)中的或者说是被释放出来的数据发送到浏览器


分析完上面的注意点,假设数据量是几百万,我们可以从以下几个方向进行优化:

  • 从数据库中进行数据量分批读取读取,以防变量内存溢出,
  • 尽量选择数据保存文件格式是csv文件,以方便导出之后的阅读、导入数据库等操作。
  • 以防不方便excel读取csv文件,我们需要104W之前就得把数据分割进行多个csv文件保存
  • 多个csv文件输出给用户下载是不友好的,我们还需要把多个csv文件进行压缩,最后提供给一个ZIP格式的压缩包给用户下载就好。


另外其他相关信息:

CSV的Excel支持GBK编码,一定要转换,否则乱码


使用linux命令 ps 或 top 命令查看进程时, 能看到内存消耗的百分比和大小
查看php运行目录命令:
which php
/usr/bin/php

ps aux | grep -c php-fpm      //查看php-fpm进程数
/usr/bin/php  -i|grep mem   //查看运行内存
/etc/init.d/php-fpm restart   //重启php-fpm

memory_get_usage 指当前脚本正在使用的内存, memory_get_peak_usage 返回分配给 PHP 内存的峰值, 举例说明:
1、 数据库读出来千万条数据,假如说需要消耗100MB,那么系统会分配给进程 100MB
2、当处理完数据后 unset 掉, 其实当前进程的消耗的内存并不会变小, 即不会释放100MB空间。unset后可以让 memory_get_peak_usage 不继续升高, 程序执行被分配的内存(进程里的内存)仍然要以 memory_get_peak_usage 为准
3、内存被分划为, "已使用" 和 "空闲", unset 只会把 "已使用" 变为 "空闲", 下次内存请求时会先去"空闲"里取, 程序结束, GC 才会释放全部内存


ob_start() : 激活php output_buffering机制,在不写参数情况下,ob_start()将php buffer空间设置
到了足够大 ,只有脚本执行结束,或者调用ob_end_flush函数,才会把数据发送给客户端浏览器。ob_start()函数内的参数可以设置output_buffering大小及输出机制。具体可以查看手册。
ob_end_flush与ob_end_clean:都会关闭ouput_buffering机制。不同的是,ob_end_flush只是把php buffer中的数据传送到浏览器,而ob_clean_clean将php bufeer中的数据清空,但不发送给客户端浏览器。

云计算解决 方案 云计算解决 方案 全文共30页,当前为第1页。 Page 2 目 录 1 云计算引领新时代潮流 2 华为云平台IDC解决 方案 3 华为桌面云解决 方案 云计算解决 方案 全文共30页,当前为第2页。 Page 3 面向IT转型,发现新增长点 新业务,新需求 已有用户业务需求日益多样化 中小企业需求 导出 "集中部署、按需取用"的新经营 思路 商业模式转型 提供基础运营平台,如App Store模式,从自己开发业务到业务集成,从卖业务到卖能力 引入互联网的"游戏规则",不仅前向收费,更需要后向收费模式 网络支撑 通用硬件和操作系统的数据中心网络平台,能支撑大 业务、自组网、可调度 能集成电信能力、WEB能力的能力开发平台,对外提供API业务集成 商业模式转型 网络平台支撑 IDC SDC OA IDC SDC OA IDC SDC OA IDC SDC OA IDC SDC OA IDC SDC OA 中心节点 中心节点 二级节点 二级节点 二级节点 二级节点 内容超市 (内容聚合) 应用超市 (应用聚合) 时钟 音乐 天气 游戏 购物 流媒体 新闻 股票 体育 电信能力组件 资源能力 它可以创建、读取、写入和编辑Excel文件(如XLSX、XLSM和XLTX),并提供了一组易于使用的API,使得处理Excel文件更加简单。3. OpenXML:直接操作底层XML结构,性能较好,但使用OpenXML SDK操作Excel文件的行和列可能显得更复杂。对于新手来说并不友好。但是,当数据 特别大,如几十万或上百万条时,我们就需要考虑如何解决服务器负载问题,以免导致程序崩溃。CSV文件本质上是纯文本文件,不能处理复杂的格式、样式、图表和其他高级Excel功能,仅支持文本和数值类型的数据。 将web页面上显示的报表 导出 到excel文件里是一种很常见的需求。然而,当数据 较大的情况下,excel本身的支持最多65535行数据的问题便凸显出来。下面就给出 大数据 导出 到excel的解决方 案。 首先,对于数据超过了65535行的问题,很自然的就会想到将整个数据分块,利用excel的多sheet页的功能,将超出65535行后的数据写入到下一个sheet页中,即通过多sheet页的方式,突破了... 最近可能会遇到大 数据 导出 Excel的场景,今天趁现在需求告一段落来做下技术预研,然后这里就顺便分享给大家。 一、数据 预判 因为我们是做物联网的,这里要 导出 的数据就是设备的上报数据。客户说要这些数据 导出 成excel进行分析,又或是其他什么原因,咱不管。咱就分析下数据 ,目前设备数 1500,2小时上报一次数据(最小可设置为半小时),要求可以 导出 3年的数据。 数据 初步估算:1500 * 12 * 30 * 12 * 3 = 19,440,000 ,设备而且据说还要上,所以估计数据 就是千万级吧。 最近在laravel做项目的时候, 导出 数据居然是后端查数据传给前端,然后前端 导出 ,导致传的数据太大而报错,并且速度极度慢,我也是方了。。现在要我改进,考虑到数据上万级别,并且现在每天都在增长,干脆一口气做到百万级别吧,参考网上的经验,自己封装了一个类,欢迎大家改正优化 CommonExport.php文件 namespace App\Exports; use App\Http\Controllers\Controller; * @author cjg 大数据 导出 Excel可以采用POI、JXL等等开源框架。目前,在项目中采用的是POI。 客户要求 导出 5w条数据,考虑到并发,这对于系统内存是个挑战,系统使用tomcat,据说tomcat的jvm内存只能升级为2g有待考证。 在网上google了半天,将结果总结如下: 1、可以采用分批 导出 ,从IBatis取出数据后,List分为几个subList,或者直接分页多次查出集合,... @Mapper public interface Inter { @Insert("insert into sysuser values('e212te','2','jjj','pwd','ljk','男',1)") int addUser(); 有参数的情况 @Mapper public interface Inter { @select("select * fr