Spring Data JPA HIbernate 批量插入速度较慢
Posted
技术标签:
【中文标题】Spring Data JPA HIbernate 批量插入速度较慢【英文标题】:Spring Data JPA HIbernate batch insert is slower 【发布时间】:2016-05-22 07:11:51 【问题描述】:我使用 Spring Data、Spring Boot 和 Hibernate 作为 JPA 提供程序,我想提高批量插入的性能。
我参考这个链接使用批处理:
http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch15.html
这是我的代码和用于插入批处理实验的 application.properties。
我的服务:
@Value("$spring.jpa.properties.hibernate.jdbc.batch_size")
private int batchSize;
@PersistenceContext
private EntityManager em;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public SampleInfoJson getSampleInfoByCode(String code)
// SampleInfo newSampleInfo = new SampleInfo();
// newSampleInfo.setId(5L);
// newSampleInfo.setCode("SMP-5");
// newSampleInfo.setSerialNumber(10L);
// sampleInfoDao.save(newSampleInfo);
log.info("starting... inserting...");
for (int i = 1; i <= 5000; i++)
SampleInfo newSampleInfo = new SampleInfo();
// Long id = (long)i + 4;
// newSampleInfo.setId(id);
newSampleInfo.setCode("SMPN-" + i);
newSampleInfo.setSerialNumber(10L + i);
// sampleInfoDao.save(newSampleInfo);
em.persist(newSampleInfo);
if(i%batchSize == 0)
log.info("flushing...");
em.flush();
em.clear();
与批处理相关的部分application.properties:
spring.jpa.properties.hibernate.jdbc.batch_size=100
spring.jpa.properties.hibernate.cache.use_second_level_cache=false
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
实体类:
@Entity
@Table(name = "sample_info")
public class SampleInfo implements Serializable
private Long id;
private String code;
private Long serialNumber;
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "sample_info_seq_gen"
)
@SequenceGenerator(
name = "sample_info_seq_gen",
sequenceName = "sample_info_seq",
allocationSize = 1
)
@Column(name = "id")
public Long getId()
return id;
public void setId(Long id)
this.id = id;
@Column(name = "code", nullable = false)
public String getCode()
return code;
public void setCode(String code)
this.code = code;
@Column(name = "serial_number")
public Long getSerialNumber()
return serialNumber;
public void setSerialNumber(Long serialNumber)
this.serialNumber = serialNumber;
运行上述批量插入 5000 行的服务需要 30 到 35 秒才能完成,但如果注释这些行:
if(i%batchSize == 0)
log.info("flushing...");
em.flush();
em.clear();
插入 5000 行仅需 5 到 7 秒,比批处理模式快。
为什么使用批处理模式会变慢?
【问题讨论】:
【参考方案1】:那是因为 EntityManager 不会立即将数据保存在数据库中。当您调用flush()
时,数据将被持久化。当您注释这些行时,EntityManager 根据 flush-mode 参数刷新数据,直接调用 flush 您告诉 EntityManager 在数据库中执行查询。
【讨论】:
那么我得到的结果是正常的吗?使用批处理总是比不使用批处理要慢,对吧? 结果正常。当您的实体可以溢出休眠会话级缓存时需要批处理,但它必须是很多实体(十倍大,然后是您的示例)。如果您不知道实体数组的大小,您可以添加批处理,但将batchSize
增加到 10 000 等
" EntityManager 在事务提交时刷新数据" 我认为这种说法是错误的。默认休眠刷新模式为自动,您无法确定刷新时间。如果刷新模式明确设置为 COMMIT,是的,这次你是对的。
jit,你是对的,我在最后一句话里也试着说同样的话。我会更正答案以上是关于Spring Data JPA HIbernate 批量插入速度较慢的主要内容,如果未能解决你的问题,请参考以下文章
Spring整合Hibernate实现Spring Data JPA
Spring-data-jpa + Hibernate 未创建预期表
简述 JPA 与 Spring Data JPA 与 Hibernate