프레임워크/Spring

[Spring] CrudRepository의 save vs saveAll

pythaac 2022. 1. 15. 23:35

  프로젝트를 하면서 데이터를 저장하는 부분을 구현하고 있었습니다. CrudRepository에는 Iterable을 input으로 여러 tuple을 저장하는 메서드인 saveAll을 제공하고 있습니다. 그런데 제가 구현하는 부분에서는 loop에서 여러 tuple을 save로 저장하고 싶었습니다. 두 메서드의 속도에 차이가 있을까요?

 

save가 오래걸리지 않을까?

  저는 단순하게 여러번 쿼리를 날리는 것보다 한 번 쿼리를 날리는 것이 더 시간이 덜 소요될 것이라 생각했습니다. 예를 들어 100개의 tuple을 저장해야한다고 했을 때, save 메서드로 tuple 하나마다 데이터베이스에 요청을 날리면, 데이터베이스는 쿼리가 올 때마다 해당 데이터를 저장하기위해 저장장치에 접근할 것이라 생각했기 때문입니다.

 

saveAll도 save의 loop로 구성

  두 메서드로 실험한 여러 글들을 확인해보면 확실히 saveAll이 더 빠릅니다. 그러나 재밌는 것은 saveAll도 save의 loop로 이루어져있다는 것입니다. 그렇다면 두 메서드의 성능 차이가 있지만, 제가 생각했던 원인은 아니라는 것입니다.

 

 

Transaction

  중요한 것은 @Transactional 어노테이션으로 표현한 트랜잭션이었습니다. 쿼리들이 언제 commit이 되는지에 따라 성능의 차이를 보이기 때문에, 메서드에 @Transaction이 붙어있는 save는 호출될 때마다 트랜잭션이 commit되며, saveAll은 save의 loop가 끝난 후에 commit되게 되어있습니다.

  그러나 트랜잭션으로 오랜 시간 lock이 되어있으면 다른 트랜잭션을 수행할 수 없어 전체적인 성능이 감소할 수 있습니다. 이에 적절히 튜닝하는 방법을 아래 블로그에서 알 수 있었습니다. 대용량 데이터를 저장할 경우 중간중간 트랜잭션을 commit하는 방식입니다.

 

https://2dongdong.tistory.com/29

 

Spring Data JPA Save(insert) 속도 최적화

대량의 데이터를 삽입하는 상황이 생겼습니다. 초창기에는 JPA Save함수를 반복문을 통해 호출해서 저장하게 구현을 했는데요. 처음에는 괜찮았으나, 삽입 할 데이터가 점점 많아지면서 삽입 시

2dongdong.tistory.com

https://sas-study.tistory.com/388

 

[Spring Data JPA] save와 saveAll의 성능 차이에 대한 실험과 결과!(스프링 프록시, @Transactional)

안녕하세요. 오늘은 Spring Data JPA를 활용할때 기본 Insert로 사용하는 save 기능과 saveAll 기능에 대한 성능 실험을 해보려고 합니다. Spring Data JPA의 경우 Bulk Insert의 경우 많은 성능 이슈를 발생시켜..

sas-study.tistory.com

https://www.baeldung.com/spring-data-save-saveall

https://stackoverflow.com/questions/49869277/spring-data-save-vs-saveall-performance

 

Spring data save vs saveAll performance

I'm trying to understand why saveAll has better performance than save in the Spring Data repositories. I'm using CrudRepository which can be seen here. To test I created and added 10k entities, wh...

stackoverflow.com