批处理 rewriteBatchedStatements=true

项目中有很多批处理,mysql提供了一个参数rewriteBatchedStatements,可以实现高性能的批量插入

MySQL的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。
MySQL JDBC驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,批量插入实际上是单条插入,直接造成较低的性能。
只有把rewriteBatchedStatements参数置为true, 驱动才会帮你批量执行SQL另外这个选项对INSERT/UPDATE/DELETE都有效

验证

  • 准备一个表
CREATE TABLE `t_user` (
  `id` bigint(20) NOT NULL,
  `user_name` varchar(45) DEFAULT NULL,
  `password` varchar(45) DEFAULT NULL,
  `nick_name` varchar(45) DEFAULT NULL,
  `id_card` varchar(45) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • 代码,批量插入100000条数据
  @GetMapping("/save")
    public String save() {
        List users = new ArrayList<>();
        Random random = new Random();
        StopWatch  stopWatch = new StopWatch("test");
        stopWatch.start("create user");
        for (int i = 0; i < 100000; i++) {
            User user = new User();
            user.setNickName("haha"+i);
            user.setIdCard("4304811992"+random.nextInt(10000)+random.nextInt(10000));
            user.setPassword(random.nextInt(10000)+"");
            user.setCreateTime(new Timestamp(System.currentTimeMillis()));
            user.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            user.setUserName("xiaohei"+i);

            users.add(user);
        }
        stopWatch.stop();
        stopWatch.start("saveBatch");
        userService.saveBatch(users);
        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());
        return "新增用户成功";
    }

1. 无rewriteBatchedStatements参数

项目中数据源配置如下,不添加rewriteBatchedStatements参数

spring:
  # 配置数据源
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true
    username: root
    password: root

执行结果

StopWatch 'test': running time = 86006762062 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
201687212  000%  create user
85805074850  100%  saveBatch

2. 有rewriteBatchedStatements参数

项目中数据源配置添加rewriteBatchedStatements参数

spring:
  # 配置数据源
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true
    username: root
    password: root

再次运行

StopWatch 'test': running time = 25266180502 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
227148131  001%  create user
25039032371  099%  saveBatch

结论

jdbc的连接串中使用rewriteBatchedStatements参数,批处理性能提升3倍。

你可能感兴趣的:(批处理 rewriteBatchedStatements=true)