美文网首页
Mybatis批量插入性能问题

Mybatis批量插入性能问题

作者: 今兮何惜 | 来源:发表于2020-02-27 19:24 被阅读0次

1、背景

业务背景是使用逻辑表达式动态的在全量的数据池中筛选出符合逻辑表达的数据,并需要持久化数据供业务使用,如筛选出逻辑表达式“x1=='y1' && (x2 =='y2' || x3 == 'y3') ”的数据,其中y1、y2、y3是x的属性。

数据总量:6w~7w条。

筛选出的数据量:12744条。

2、最初的方案和存在的问题

使用Mybatis的foreach语句,将待插入数据批量入库。

耗时:10min。

机器现象:CPU飙升至80%+,负载偏高,5分钟、10分钟、15分钟都超过2.

3、优化方案

方案一:将12744条语句分批次插入,每次插入少量。分别尝试5000条、2000条、1000条、500条和100条并观察,结果如下:

         5000条:单批次耗时在130s左右,CPU及机器负载高;

         2000条:单批次耗时在80s左右,CPU及机器负载高;

         1000条:单批次耗时在20s左右,CPU及机器负载高;

          500条:  单批次耗时在10s左右,CPU及机器负载高;

          100条:单批次耗时3s左右。

方案二:使用mybatis的batch模式,手动commit,分批次入库,尝试5000批次和2000批次,耗时均在1~2s内,如下代码:


        SqlSession sqlSession = sqlSessionFactory.openSession(
                ExecutorType.BATCH, false);
        try {
            Mapper mapper = sqlSession
                    .getMapper(Mapper.class);
            List<Dimension> tempList = new ArrayList<Dimension>();
            for (int i = 0; i < items.size(); i++) {
                tempList.add(items.get(i));
                if (tempList.size() >= batch) {
                    mapper.addById(id, tempList);
                    sqlSession.commit();
                    tempList.clear();
                }

            }
            if (tempList.size() > 0) {
                mapper.addById(id, tempList);
                sqlSession.commit();
            }
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            sqlSession.close();

        }


相关文章

网友评论

      本文标题:Mybatis批量插入性能问题

      本文链接:https://www.haomeiwen.com/subject/bpozchtx.html