最近做的项目领导要求把上一期的大量数据的导出做一下优化,到手之后测试发现,dao层用的是spring的JdbcTemplate,在service层用循环控制每次去数据库取出5000条数据回来,然后封装进List中,再用POI写出数据,如此循环.测试的结果是,导出7万数据的时候需要6分钟,导出14万数据需要将近20分钟,导出60+万数据基本瘫痪,下载2-3M就一直不动弹.想了想就把dao层改成了原生的JDBC,测试发现下载速度翻了几翻,但是到了百万级又死了......,然后经一前辈提醒ResultSet不会占用内存...所以有了下面的代码,可能有点糙....
//通过Connection获取prepareStatement searchPageSql是拼接sql语句 total是查询的数据总量
pstmt = conn.prepareStatement(searchPageSql(searchBean, tableName, carrier, 0, total),
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
//设置prepareStatement每次抓取数据库数据的长度
pstmt.setFetchSize(20000);
//设置抓取的方向
pstmt.setFetchDirection(ResultSet.FETCH_REVERSE);
//执行得到ResultSet结果集
rs = pstmt.executeQuery();
//创建一个长度为10000的List
List<Map<String, Object>> extractData = new ArrayList<Map<String, Object>>(10000);
while (rs.next()) {
//当List长度为10000的时候开始写入数据
if (extractData.size() >= 10000) {
代码省略......
下面是我测试过程中记录的部分数据:
原来导出7w条数据需要的时间是++++++++380293毫秒 封装5000条 Fetchsize500
原来导出7w条数据需要的时间是++++++++219282毫秒 封装10000条 Fetchsize500
原来导出7w条数据需要的时间是++++++++215875毫秒 封装10000条 Fetchsize500
JDBC导出68.6w数据共花费的时间是+++++376830毫秒 封装10000条 Fetchsize1000
JDBC导出68.6w数据共花费的时间是+++++404370毫秒 封装20000条 Fetchsize1000
JDBC 使用resultSet导出241w数据共花费的时间是+++++757370毫秒 封装20000 Fetchsize10000
这篇文章不错:http://blog.sina.com.cn/s/blog_670620330101n8dz.html