导出的速度一般情况下要比导入慢
问题出现的原因
导入过慢
为了弄清楚导入过慢的原因,让我们先理一理EasyExcel导入的大致流程:
读取Excel的数据->数据处理->连接数据库->插入到数据库
可以看到,流程很简单,一般情况下,数据处理和连接数据库的操作对于我们来说,可优化点比较少,以及优化的性价比不高,那么我们优化的步骤就是如何快速读取excel中的数据,以及如何将大量数据插入到数据库中去
优化从excel读取数据的速度
继续分析,当数据量非常多的时候,如果是一次性读取excel中的数据,可能会造成我们内存溢出,而当内存到达一定程度时,会导致整个系统的性能都有所下降,因此我们可以批量读取写入,每次读取个10w, 20w,相同的数据量情况下,分批次读取所有数据的时间要比一次性读取所有数据的时间要少,我们只需要重写相应的写入方法,添加一个判断即可,例子如下:
代码语言:java复制// 创建读取监听器
AnalysisEventListener listener = new AnalysisEventListener() {
private static final int BATCH_SIZE = 100000; // 每批次读取的数据量
private List<Object> dataList = new ArrayList<>(); // 存储每批次读取的数据
@Override
public void invoke(Object data, AnalysisContext context) {
// 处理每行数据
dataList.add(data);
// 达到批次读取的数据量时进行处理
if (dataList.size() >= BATCH_SIZE) {
processData(dataList); // 处理当前批次数据
dataList.clear(); // 清空数据列表,准备读取下一批数据
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 处理剩余的数据
if (!dataList.isEmpty()) {
processData(dataList);
}
// 可以在这里进行最终的收尾工作
}
// 自定义处理每批数据的方法
private void processData(List<Object> data) {
// 处理当前批次的数据
System.out.println("Processing batch of data: " data.size() " rows");
}
};
// 创建 Excel 读取器并设置监听器
ExcelReader excelReader = EasyExcel.read("file.xlsx", dataModel.class, listener)
.build();
// 读取 Excel 数据
excelReader.read();
// 关闭 Excel 读取器
excelReader.finish();
- 另外,easyexcel读取的默认线程数为1,我们可以根据需要将其设置为多线程,只需要在创建reader的时候声明即可,例如:
ExcelReader excelReader = EasyExcel.read("file.xlsx", dataModel.class, listener)
.readSheetThread(5) // 设置并发线程数为 5
.build();
值得注意的是如果你是双管齐下的话,要保证监听器中重写的方法需要做好多并发处理
优化数据库的插入速度
- 大部分数据库插入操作,花费的时间往往在建立链接上,因此我们可以直接批量写入数据到mysql加上事务的方式,同时也要注意不要一次性写入过多数据, 不然可能导致内存占用过高以及锁竞争问题出现,
- 为什么要批量插入想必大家都知道,那么为什么要加上事务呢?
原因如下:
- 可以回滚,如果有一条数据插入错误,那么可能会出现数据不一致,而数据不一致又进一步可能影响到数据插入,这也就是为什么内存足够的情况下,如果有大量数据插入的话,一次性写入速度要更快(如果插入的数据都没问题的话), 但还是选择分批写入加上事务
导出过慢
- 数据读取过慢,写入到excel中过慢
优化数据库读取
- 常见的sql优化,想必大家都知道,这里不做过多解释,如下,分批读取,索引优化,使用连接池......
优化写入
easyexcel默认是一行一行写入,频繁涉及IO操作,我们可以设置成批量写入到excel中
分sheet写入,同一sheet写入大量数据,会导致内存占用过高,以及IO操作频繁
采取SXSSFWorkbook,**在处理大量数据时这中写入方式会比另外的XSSFWorkbook和HSSFWorkbook占优点,这种模式在数据到达一定程度时,内存中的数据会背转移到磁盘中去,从而一定程度上避免了大量数据写入导致的内存占用过高问题