博客
关于我
Mysql 批量修改四种方式效率对比(一)
阅读量:797 次
发布时间:2023-02-10

本文共 4536 字,大约阅读时间需要 15 分钟。

Mysql 批量修改四种方式效率对比

环境信息

  • 数据库版本:mysql-5.7.12
  • 运行环境:mac pro
  • 开发工具:idea(分配最大内存2g)

测试数据

  • 数据量:10万
  • 数据生成方式:通过循环生成唯一的id、firstName和lastName

依赖管理

org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-web
org.project.lombok
lombok
1.18.12
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.2
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine

数据库结构

CREATE TABLE `people` (    `id` bigint(8) NOT NULL AUTO_INCREMENT,    `first_name` varchar(50) NOT NULL DEFAULT '',    `last_name` varchar(50) NOT NULL DEFAULT '',    PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

初始化测试数据

@Testvoid init10wData() {    for (int i = 0; i < 100000; i++) {        People people = new People();        people.setFirstName(UUID.randomUUID().toString());        people.setLastName(UUID.randomUUID().toString());        peopleDAO.insert(people);    }}

批量修改方案

第一种:for循环

update people
first_name = #{item.firstName,jdbcType=VARCHAR}
last_name = #{item.lastName,jdbcType=VARCHAR}
where id = #{item.id,jdbcType=BIGINT}

第二种:case when

update people
when id=#{i.id} then #{i.firstName}
when id=#{i.id} then #{i.lastName}
where id in
#{item.id,jdbcType=BIGINT}

第三种:replace into

replace into people (id, first_name, last_name) values
(#{item.id}, #{item.firstName}, #{item.lastName})

第四种:ON DUPLICATE KEY UPDATE

insert into people (id, first_name, last_name) values
(#{item.id}, #{item.firstName}, #{item.lastName})
ON DUPLICATE KEY UPDATE id=values(id), first_name=values(first_name), last_name=values(last_name)

测试代码

@Testvoid updateBatch() {    List
list = new ArrayList<>(); int loop = 100; int count = 100000; Long maxCost = 0L; Long minCost = Long.valueOf(Integer.MAX_VALUE); System.out.println("开始"); Long startTime = System.currentTimeMillis(); for (int j = 0; j < count; j++) { People people = new People(); people.setId(ThreadLocalRandom.current().nextLong(0, 100000)); people.setFirstName(UUID.randomUUID().toString()); people.setLastName(UUID.randomUUID().toString()); list.add(people); } for (int i = 0; i < loop; i++) { Long curStartTime = System.currentTimeMillis(); peopleDAO.updateBatch4(list); Long curCostTime = System.currentTimeMillis() - curStartTime; if (maxCost < curCostTime) { maxCost = curCostTime; } if (minCost > curCostTime) { minCost = curCostTime; } System.out.println("耗时-" + (System.currentTimeMillis() - curStartTime)); } System.out.println("结束"); System.out.println("平均-" + (System.currentTimeMillis() - startTime) / loop + "ms"); System.out.println("最小-" + minCost + "ms"); System.out.println("最大-" + maxCost + "ms");}

效率比较

数据量 for循环 case when replace into ON DUPLICATE KEY UPDATE
500 100次 100次 100次 100次
1000 100次 100次 100次 100次
5000 100次 100次 100次 100次
10000 10次 10次 100次 100次
50000 10次 卡死不动 100次 100次
100000 10次 卡死不动 100次 100次

总结

  • for循环:效率相当高,但大量数据可能导致SQL阻塞。
  • case when:虽然循环次数较多,但每条SQL只执行一次,适合小批量数据。
  • replace into:在大批量数据下容易导致数据丢失,且公司通常禁止使用。
  • ON DUPLICATE KEY UPDATE:效率最高,但由于可能导致数据丢失,通常不推荐使用。

参考文章:

  • mybatis批量更新数据三种方法效率对比
  • MySql中4种批量更新的方法
  • 你可能感兴趣的文章
    Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
    查看>>
    Webpack 之 basic chunk graph
    查看>>
    Mysql5.7版本单机版my.cnf配置文件
    查看>>
    mysql5.7的安装和Navicat的安装
    查看>>
    mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
    查看>>
    Mysql8 数据库安装及主从配置 | Spring Cloud 2
    查看>>
    mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
    查看>>
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>
    MYSQL8.0以上忘记root密码
    查看>>
    Mysql8.0以上重置初始密码的方法
    查看>>
    mysql8.0新特性-自增变量的持久化
    查看>>
    Mysql8.0注意url变更写法
    查看>>
    Mysql8.0的特性
    查看>>
    MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    查看>>
    MySQL8修改密码的方法
    查看>>
    Mysql8在Centos上安装后忘记root密码如何重新设置
    查看>>
    Mysql8在Windows上离线安装时忘记root密码
    查看>>
    MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
    查看>>
    mysql8的安装与卸载
    查看>>
    MySQL8,体验不一样的安装方式!
    查看>>