前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >导入导出百万级数据时过慢该如何优化?

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

原创
作者头像
天下之猴
修改2024-09-06 19:16:12
910
修改2024-09-06 19:16:12
举报

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

问题出现的原因

导入过慢

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题出现的原因
    • 导入过慢
      • 优化从excel读取数据的速度
      • 优化数据库的插入速度
    • 导出过慢
      • 优化数据库读取
      • 优化写入
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档