Shellbye.github.io icon indicating copy to clipboard operation
Shellbye.github.io copied to clipboard

Spring Boot JPA Hibernate saveAll 速度慢原因调查与调优

Open Shellbye opened this issue 6 years ago • 2 comments

最近新开发一个项目(demo),有大量的数据批量保存,用到了JPA自带的saveAll方法,但是在压测的时候,却发现一个致命的问题,就是特别慢。用MySQLshow PROCESSLIST;查看之后,发现有大量的如下语句

select next_val as id_val from hibernate_sequence for update

原来是因为在model中的id是由Hibernate生成的,

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

而它的生成机制就是在hibernate_sequence这个表中存储了下一个id,并在每一次取的时候都自增,所有的新建请求都需要在这里排队取id,那可不是就慢了,这就导致saveAll和重复调用save一样了,批量操作失去了批量的意义,避免这种假批量的方式比较多,比较简单快捷的一个方式就是在配置文件中显示的关闭这种策略

spring.jpa.hibernate.use-new-id-generator-mappings=false

这样配置之后,同样的model代码

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

其生成id的功能将由数据库来完成,这样就会快很多,起码是多线程,而不是排队的单线程了。

Shellbye avatar Feb 23 '19 14:02 Shellbye

原来如此,怪不得我也这么慢,才35w数据,要存几十分钟

ninjachen avatar May 30 '19 08:05 ninjachen

原来如此,怪不得我也这么慢,才35w数据,要存几十分钟

这个机制是有点坑

Shellbye avatar May 30 '19 08:05 Shellbye