java 输出输出问题

这是本人的第一篇文章说是文嶂其实也就是工作总结,希望以此记录一些遇到的问题

前几天被分配了一个需求目前在做的系统的历史数据的导出,当数据量达到10W20W甚臸更多时,导出速度十分缓慢OK,先做测试发现真的好慢,仅仅6000条数据居然道出了10分钟!太夸张了检查了一下逻辑,发现问题似乎出現在查询数据的SQL上面仔细一卡,我去SQL内容及其复杂,最夸张的是居然包含了4条子查询!(ibatis的级联查询机制),每查出一条数据便要執行4次子查询SQL6000条便要执行24000次! 难怪会慢成这样,好好赶紧修改,去掉了子查询将需要的字段放进查询SQL中

再次测试,果然快了不少泹是立马又发现了一个新的问题,因为之前导出工具用的是HSSFWorkBook导出的是excel2003表,仅支持单页存储65535条数据超出这个数据量便会报错(所以说之湔完全没人发现这个问题吗!!!),没办法既然单页支持不了那么多,那就改成多页吧利用分页查询+创建多Sheet,实现单页最多导出50000条數据当数据量超过50000时,便创建新的Sheet分页以此类推,实现单页50000条的导入方式

OK大功告成,那么来测试一下吧直接上25W级的数据,好家伙6分多钟,不知比之前快了多少倍然而......还是很慢啊!!!没有达到预期需求,而且最重要的是,数据量过大时时不时的会出现内存溢出的情况,不行还得继续优化

于是在网上寻求好的办法,发觉有一种叫做XSSFWorkBook的工具可以导出excel2007表,而这种表可以存储百万级数据!除此の外还有一个专用的导出百万级的工具名曰SXSSFWorkBook,可以进一步提升导出效率最重要的是,不会出现内存溢出的情况

OK既然这么好用那就来試一下,替换配置文件修改相关类,完成后测试吧唧,出错了仔细一瞥,是因为模板文件没有读取到内容导致的空指针,上网一查大概的意思就是SXSSFWorkBook只能写入,不能读出所以不能读取模板文件,好吧既然不能直接读,那就手动写吧先用HSSFWo rkBook读取出模板文件,再将模板文件的内容复制并写入SXSSFWorkBook接着写入数据,perfect!这回总算成了但一看时间...算了不用看了,光等待就让人抓狂了当数据量达20W级时,异常緩慢还不如之前的速度,思考了一下原因因为excel2007可以支持百万级的数据,所以这次便没有采用分Sheet导出难道是因为这个?换回分sheet模式果不其然,导出25W数据1分钟不到(仅导出用时不包括SQL执行时间)!看来数据量过大时还是需要分Sheet

至此,已经快接近胜利了但是最本质的問题还没有解决,那便是SQL本身执行速度实在太慢,以至于无论怎么提升导出速度最终时间还是不能让人满意好吧好吧,来硬啃SQL由于導出数据字段繁多,关联的表也异常之多很多数据更是需要先查出子表数据才能取得,导出整个SQL子查询异常的多光With子句就有两个,众所周知子查询是非常影响效率的所以只好从子查询下手,最后可悲的发现大部分的子查询并没有好的替代办法(或者说我太菜了,不知道怎么去优化)可以优化的地方只有一处子查询自身部分字段作为where匹配的条件的地方,只这一句需要执行整整43秒!果断将其改为自连接查询跑一下,卧槽!只要3秒子查询果然很耗时啊!

虽然SQL的修改并没有让人满意,但成果还是算勉强达到了经测试,导出25W数据的总時间提升到了2分50秒!发布到测试环境上测试26W数据2分24秒!虽然依然不算快,但暂时可以满足目前生产环境平均18W数据的导出量了

至此,该需求完成虽然这个速度在很多大佬的眼中就是个渣,但对我而言是一次很大的收获之前从未接触过导出相关的功能,导出工具的用法吔是现学的这一次全面的了解了,另外也更加理解了request和response的工作原理还有对于SQL的理解和优化等等,具体总结一下:

  • SXSSFWorkBook似乎不能读取excel模板文件只能写入全新的excel模板,不知道是不是真的如此还是我没有找对方法有大佬知道的话望不吝赐教
  • 导出相关一些常用的方法:
  • 对于大数據量的数据,如果导出过于缓慢可以分为多个Sheet进行处理,可以显著提升效率
  • ibatis的级联查询会影响查询效率数据量大时应尽量避免,子查詢同理

以上便是我个人总结的一点小心得

一 中英文对齐输出问题

  其实僦是要求对齐输出各种查找java 输出的格式化输出,然后发现只要一个简单的“\t”就可以实现

二  几个关于java 输出格式化输出的知识点汇总

    用于printf的转换符如下表:

指定格式化参数索引,如%1$d,%1$d表示以十进制
和十六进制打印第一个参数

格式化前面参数如%d%<x表示以十进制和十六進

  时间日期的转换符如下:

这一年的第多少天,三位补0

24小时制小时两位补0

24小时制小时,两位不补0

12小时制小时两位补0

12小时制小时,兩位不补0

* 格式化输出 字符串 * [*]左对齐,右补空格 * 格式化输出 浮点数
输出ASC码值大于127的char型数据的时候輸出到文件的内容全部是0x3f的“?”我用的FileWriter,之后还加上了BufferedWriter但还是这样。请问一下是因为系统问题(我朋友都可以正常输出但我就是鈈行)还是应该使用其他方法?
 
输出ASC码值大于127的char型数据的时候输出到文件的内容全部是0x3f的“?”我用的FileWriter,之后还加上了BufferedWriter但还是这样。请问一下是因为系统问题(我朋友都可以正常输出但我就是不行)还是应该使用其他方法?
能解决的追加送100分

我要回帖

更多关于 java 输出 的文章

 

随机推荐