10W条excel数据入库效率提升小结

一、需求:
使用poi读取国民经济行业分类表(国家统计局搞的excel表格),同时将数据插入已建好的MySQL表中。

二、采用框架:
springboot + MyBatisPlus(框架只用于测试,重点在于思路,而不在于使用什么框架)

三、测试:

  1. 使用最基本的逐条获取excel记录放入list中,在循环比例 逐条插入,计算耗时10W条excel数据入库效率提升小结_第1张图片
@Test
    public void test01() throws IOException {
        Workbook wb = PoiUtils.readExcel("G:\\industry.xlsx");
        if (wb != null){
            Sheet sheet = wb.getSheetAt(0);
            int maxRowNum = sheet.getPhysicalNumberOfRows();
            System.out.println(maxRowNum);
            Row row = null;
            row = sheet.getRow(3);
            System.out.println(row.getCell(0).getStringCellValue());
            System.out.println(row.getCell(3).getStringCellValue());
            List rowList = new ArrayList<>();
            for (int i = 3;i < maxRowNum;i++){  //记录总条数 2W+
                row = sheet.getRow(i);
                if (row != null && !PoiUtils.isRowEmpty(row)){
                    if (row.getCell(3) != null){
                        //将单元格数据类型设置为字符串类型
                        row.getCell(3).setCellType(CellType.STRING);
                        rowList.add(row.getCell(3).getStringCellValue());
                    }
                }
            }
            wb.close();
            //到此成功取出Excel中每行第一列与第四列数据
            long begin = System.currentTimeMillis();
            for (String s:rowList){
                Test001Entity test001Entity = new Test001Entity();
                test001Entity.setContent(s);
                test001Service.save(test001Entity);
            }
            long end = System.currentTimeMillis();
            System.out.println("总时间:" + (end-begin));
        }
    }

结果:总耗时 — 714325ms 差不多 12分钟
10W条excel数据入库效率提升小结_第2张图片
2. 可见使用逐条插入效率极低,为了提高效率,下面使用MyBatis的循环标签 foreach优化

先使用SQL客户端清空(TRUNCATE tableName)表记录
10W条excel数据入库效率提升小结_第3张图片
10W条excel数据入库效率提升小结_第4张图片

动态SQL如下:
10W条excel数据入库效率提升小结_第5张图片
控制台打印信息如下
在这里插入图片描述
结果:总耗时 — 1822ms 差不多 1.8秒
10W条excel数据入库效率提升小结_第6张图片

3.OK,到目前为止,2W条的记录入库尚可在接收范围内入库,但存在问题,excel放入集合中,仅仅只是一个简单的字符串,数据量并不大,其次,2W条数据有点少,这下加到10W在进行一波测试:
10W条excel数据入库效率提升小结_第7张图片
在进行一波测试:
结果如下,直接报错,报错原因:数据库最大允许的包大小不够
在这里插入图片描述
解决方案之一:数据库的配置文件中,将 max_allowed_packet 属性加大,这样当然也有问题,我们并不清楚具体包的大小该设为多少,若需求的文件记录大于1000W呢?这样会导致频繁调整数据库配置,不利于生产实际。

解决方案二:
对 list进行拆分,给定一个临界值,分批插入
10W条excel数据入库效率提升小结_第8张图片

public void compute(List list,int start,int end) {
        final int THRESHOLD = 20000;    //临界值
        int length = end -start;
        if (length <= THRESHOLD){
            List temList = new ArrayList<>();
            for (int i = start;i < end;i++){
               temList.add(list.get(i));
            }
            test001Service.multiSave(temList);
        }else {
            int middle = (start + end)/2;
            compute(list,start,middle);
            compute(list,middle + 1,end );
        }
    }

10W条excel数据入库效率提升小结_第9张图片
结果如下:
10W条excel数据入库效率提升小结_第10张图片
此为单线程进行数据录入,之后会更新使用多线程方式提高效率
https://blog.csdn.net/weixin_43762117/article/details/95592268

你可能感兴趣的:(效率优化)