导入导出百万级数据时过慢该如何优化?

2024-09-06 19:16:12 浏览数 (2)

导出的速度一般情况下要比导入慢

问题出现的原因

导入过慢

为了弄清楚导入过慢的原因,让我们先理一理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的时候声明即可,例如:
代码语言:java复制
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占优点,这种模式在数据到达一定程度时,内存中的数据会背转移到磁盘中去,从而一定程度上避免了大量数据写入导致的内存占用过高问题

0 人点赞