10w 行级别数据的 Excel 导入优化记录

这篇博客记录了优化10w行级别数据的Excel导入过程,通过EasyPOI+缓存数据库查询操作+批量插入进行初步优化,然后使用EasyExcel进一步提高效率。在数据插入速度上,通过限制SQL长度和采用并行流实现多线程插入,将10w行数据导入时间缩短至95秒。博主分享了自定义SessionMapper、MapResultHandler、批处理和并行插入工具类等关键代码片段。
摘要由CSDN通过智能技术生成
  • 写入当前行数据

3、返回执行结果,如果出错 / 校验不合格。则返回提示信息并回滚数据

显而易见的,这样实现一定是赶工赶出来的,后续可能用的少也没有察觉到性能问题,但是它最多适用于个位数/十位数级别的数据。存在以下明显的问题:

  • 查询数据库的校验对每一行数据都要查询一次数据库,应用访问数据库来回的网络IO次数被放大了 n 倍,时间也就放大了 n 倍

  • 写入数据也是逐行写入的,问题和上面的一样

  • 数据读取使用原生 POI,代码十分冗余,可维护性差。

第二版:EasyPOI + 缓存数据库查询操作 + 批量插入

针对第一版分析的三个问题,分别采用以下三个方法优化

缓存数据,以空间换时间

逐行查询数据库校验的时间成本主要在来回的网络IO中,优化方法也很简单。将参加校验的数据全部缓存到 HashMap 中。直接到 HashMap 去命中。

例如:校验行中的房屋是否存在,原本是要用 区域 + 楼宇 + 单元 + 房号 去查询房屋表匹配房屋ID,查到则校验通过,生成的欠单中存储房屋ID,校验不通过则返回错误信息给用户。而房屋信息在导入欠费的时候是不会更新的。并且一个小区的房屋信息也不会很多(5000以内)因此我采用一条SQL,将该小区下所有的房屋以 区域/楼宇/单元/房号 作为 key,以 房屋ID 作为 value,存储到 HashMap 中,后续校验只需要在 HashMap 中命中

自定义 SessionMapper

Mybatis 原生是不支持将查询到的结果直接写人一个 HashMap 中的,需要自定义 SessionMapper

SessionMapper 中指定使用 MapResultHandler 处理 SQL 查询的结果集

@Repository

public class SessionMapper extends SqlSessionDaoSupport {

@Resource

public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {

super.setSqlSessionFactory(sqlSessionFactory);

}

// 区域楼宇单元房号 - 房屋ID

@SuppressWarnings(“unchecked”)

public Map<String, Long> getHouseMapByAreaId(Long are

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>