Jpa JdbcTemplate 批量插入效率对比

使用两种方式

  • Jpa 默认插入方法(项目默认使用hypersistence utils 优化的BaseJpaRepository)
  • JdbcTemplate 执行 批量SQL

yml 开启JPA 批量配置

yaml 复制代码
    jpa:
    properties:
      hibernate:
        #格式胡sql 语句
        format_sql: false
        # 开启批量插入
        jdbc:
          batch_size: 1000
          batch_versioned_data: true
          order_inserts: true
          order_updates: true


    # 来自网络,rewriteBatchedStatements=true ,但测试发现并无影响
    url: jdbc:p6spy:mysql://127.0.0.1:3306/xxxx?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true

通知公告为例

插入5000条 数据耗时分析(数据库ID 自增)

java 复制代码
@Override
public boolean save(Notice notice) {        
        StopWatch sw = new StopWatch();

        sw.start("单条入库");
        noticeDao.persist(notice);
        sw.stop();

        List<Notice> noticeList = new ArrayList<>(5000);
        notice.setId(null);
        for (int i = 0; i < 5000; i++) {
        Notice copy = notice.copy();
        copy.setTitle("通知公告" + i);

        noticeList.add(copy);
        }
        sw.start("JPA 插入数据库");
//        persistAll
        noticeDao.persistAllAndFlush(noticeList);
        sw.stop();

        sw.start("JDBC插入 单次5k");
        //  使用雪花ID
        Snowflake snowflake = new Snowflake();
        StringBuilder sb = new StringBuilder("INSERT INTO `smiletest`.`biz_notice`(`id`, `title`, `parent_id`, `json_str`, `notice_time`, `create_time`, `update_time`, `create_by`, `update_by`) VALUES");
        sb.append(" (").append(snowflake.nextId()).append(", '通知公告', NULL, '[]', '2023-11-08 09:42:26', '2023-11-08 09:42:41', '2023-11-08 09:42:41', 2927901808918528, 2927901808918528)");

        for (int i = 0; i < 5000; i++) {
        sb.append(" ,(").append(snowflake.nextId()).append(", '通知公告', NULL, '[]', '2023-11-08 09:42:26', '2023-11-08 09:42:41', '2023-11-08 09:42:41', 2927901808918528, 2927901808918528)");
        }
        sb.append(";");
        jdbcTemplate.execute(sb.toString());
        sw.stop();

        sw.start("JDBC插入 2k/次,循环100次 20w");
        sb = new StringBuilder("INSERT INTO `smiletest`.`biz_notice`( `title`, `parent_id`, `json_str`, `notice_time`, `create_time`, `update_time`, `create_by`, `update_by`) VALUES");
        sb.append(" ('通知公告', NULL, '[]', '2023-11-08 09:42:26', '2023-11-08 09:42:41', '2023-11-08 09:42:41', 2927901808918528, 2927901808918528)");

        sb.append(" ,('通知公告', NULL, '[]', '2023-11-08 09:42:26', '2023-11-08 09:42:41', '2023-11-08 09:42:41', 2927901808918528, 2927901808918528)"
        .repeat(2000));
        sb.append(";");
        for (int i = 0; i < 100; i++) {
         jdbcTemplate.execute(sb.toString());
        }
        sw.stop();
        
        System.out.println(sw.prettyPrint(TimeUnit.SECONDS));
        System.out.println(sw);
        return true;
}

日志输出

log 复制代码
StopWatch '': running time = 22 s
---------------------------------------------
s         %     Task name
---------------------------------------------
000000000  00%   单条入库
000000012  57%   JPA 插入数据库
000000000  02%   JDBC插入 单次5k
000000009  41%   JDBC插入 2k/次,循环100次 20w

StopWatch '': running time = 22338138700 ns; 
[单条入库]         
17840900 ns = 0%; 
[JPA 插入数据库]     
12799729300 ns = 57%; 
[JDBC插入 单次5k]    
345819100 ns = 2%; 
[JDBC插入 2k/次,循环100次 20w]  
9174749400 ns = 41%

不开JPA 批量配置,hypersistence utils 的BaseJpaRepository 有默认优化。

log 复制代码
StopWatch '': running time = 23 s
---------------------------------------------
s         %     Task name
---------------------------------------------
000000000  01%   单条入库
000000013  59%   JPA 插入数据库
000000000  02%   JDBC插入 单次5k
000000009  39%   JDBC插入 2k/次,循环100次 20w

总结

Jpa配置开启批量配置后,5K数据,batch_size 500 需19秒,1000需13秒。 jdbcTemplate 5k 毫秒级,20w 9秒遥遥领先。

在模块开发效率和性能效率之间 抉择就是了,Jpa ORM框架,切换数据库无sql影响。但jdbcTemplate 则需确认SQL语句是否兼容。

相关推荐
一只爱打拳的程序猿10 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
ajsbxi3 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
鹿屿二向箔4 小时前
基于SSM(Spring + Spring MVC + MyBatis)框架的咖啡馆管理系统
spring·mvc·mybatis
NoneCoder5 小时前
Java企业级开发系列(1)
java·开发语言·spring·团队开发·开发
paopaokaka_luck11 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
Yaml413 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
aloha_78913 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
wyh要好好学习15 小时前
SpringMVC快速上手
java·spring
尢词15 小时前
SpringMVC
java·spring·java-ee·tomcat·maven
wrx繁星点点16 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式