1、 前言php
财务在每个月月底作财务数据统计时,须要统计每个月产品的出货单及退货单报表数据,故要求在每个月月底要汇总当月的报表数据,每一季度或者半年也要相应的统计报表数据,并能把数据导出到excl表格,因此数据报表导出功能则是必然的。财务提供的excel表格字段繁多,汇总下关联到数据库表达到7张以上,故在进行出货单或者退货单报表查询之时,因为涉及到多张表关联,故每次查询都须要耗费至关多的时间和空间。html
2、 实现前端
数据报表只须要按照起始时间和结束时间进行查询和导出。以出货单为例,历史数据累计至今的出货单以上万至几十万之多。早期的导出功能是实时查询并导出,在选择时间段进行数据导出之时,若是时间跨度太大,后台执行过久的话会致使前端页面显示错误信息,或者等待时间过长让财务人员误觉得导出失败,用户体验也不是很好。mysql
3、 优化sql
a) 从服务器架设上优化数据库
考虑到咱们是采用LAMP的服务器架构,PHP是部署到Linux环境下,能够尝试利用Linux提供的工具配合PHP使用。缓存
用户使用的场景主要是财务人员查询的基本上都是历史或者已成型的数据,故咱们能够在服务器空闲期间使用PHP-CLI方式后台执行生成数据并插入到新设计的数据表中,用户在使用过程当中能够选取缓存数据导出报表的方式来生成excel数据。借助于Linux环境下Crontab工具能够实现此情景。具体的Crontab命令参考以下:服务器
/usr/local/php-5.4.26/bin/php 架构
-f /data/www/wms/index.php cli/crontab_report/export_to_db框架
b) 分批执行
后台执行Crontab命令之时,若是一次性把全部数据经过SQL检索出来再进行插入的话,在中间若是出现异常退出之时,则会致使前期所作的工做付之流水。且PHP自己在执行期间是会耗费内存的,是有可能出现异常退出的状况,故能够采用相似分页查询的方式对数据进行分批处理并插入。目前采用的是每一批次采用300条出货单检索并插入。
c) PHP执行内存设置
在PHP脚本执行期间,是有内存消耗的,正常状况下在PHP执行完脚本以后会自动释放相应内存,但若是当前执行的脚本将要花很长时间并占用比较大的资源之时,则会致使PHP执行内存达到必定上限而致使异常退出。使用PHP提供的memory_get_usage()函数咱们能够查看在后台执行PHP脚本所耗费的内存。采用上述B分批执行方式,每一批次采用300条数据检索并插入,计算出内存差可算出检索出300条记录须要耗费大体1.6M内存,插入操做消耗128K数据,查询PHP配置参数memory_limit为96M,实际可插入数据13000-15000左右数据以后则会异常退出,而且查不出错误信息。
咱们能够经过增大memory_limit参数值来延长PHP执行时间,有三种方式能够设置此参数,一种是修改php.ini中的memory_limit参数,此方式对整个php环境影响较大,也可使用ini_set()函数临时设置为指定的memory_limit大小,一样的在相应网站有.htaccess文件的时候也能够修改相似以下php_value memory_limit 16M。实际测试环境下,经过ini_set设置memory_limit为256M之时,实际可插入的数据达到42077条。
d) 执行期间实时释放相应内存
上述C方式是采用扩大memory_limit的值来延长PHP的执行时间,但仍不可避免有些历史数据是没法生成的,表现为只能缓存以前4-5个月数据,固然此状况也基本知足要求。上述提到在检索300条记录时须要耗费1.7M内存,这消耗的资源是挺大的,咱们能够采用相似C语言的方式,在不须要的时候把它释放掉,上述情景主要都是与数据库相关,咱们只要保证在检索到相应参数并确认此在后续无用之时把他释放掉,相应PHP函数是mysql_free_result,CI框架已作了封装,调用CI的free_result函数便可。一样的相应的数据在使用完以后能够经过unset函数来释放相应的PHP内存。
4、 参考文档
http://blog.chinaunix.net/uid-17085332-id-2832158.html
2)PHP查看内存使用状况: