1. 개요
이 빠른 사용방법(예제)에서는 Spring Data의 save() 및 saveAll() 메서드 간의 성능 차이에 대해 알아봅니다 .
2. 신청
성능을 테스트하려면 엔티티와 저장소가 있는 Spring 애플리케이션이 필요합니다.
책 엔터티를 만들어 보겠습니다.
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String title;
private String author;
// constructors, standard getters and setters
}
또한 저장소를 생성해 보겠습니다.
public interface BookRepository extends JpaRepository<Book, Long> {
}
3. 성능
성능을 테스트하기 위해 두 가지 방법을 모두 사용하여 10,000권의 책을 저장합니다.
먼저 save() 메서드를 사용합니다 .
for(int i = 0; i < bookCount; i++) {
bookRepository.save(new Book("Book " + i, "Author " + i));
}
그런 다음 책 List을 만들고 saveAll() 메서드를 사용하여 한 번에 모든 책 을 저장합니다.
List<Book> bookList = new ArrayList<>();
for (int i = 0; i < bookCount; i++) {
bookList.add(new Book("Book " + i, "Author " + i));
}
bookRepository.saveAll(bookList);
테스트에서 첫 번째 방법은 약 2초가 소요되고 두 번째 방법은 약 0.3초가 소요되는 것으로 나타났습니다.
또한 JPA 배치 삽입을 활성화했을 때 save() 메서드 의 성능이 최대 10% 감소 하고 saveAll() 메서드 의 성능 이 최대 60% 증가 하는 것을 관찰했습니다 .
4. 차이점
두 메서드의 구현을 살펴보면 saveAll() 이 각 요소를 반복하고 각 반복에서 save() 메서드를 사용 한다는 것을 알 수 있습니다 . 이는 성능 차이가 그렇게 크지 않아야 함을 의미합니다.
더 자세히 살펴보면 두 메서드 모두 @Transactional 로 어노테이션 처리되어 있음을 알 수 있습니다.
또한 기본 트랜잭션 전파 유형은 REQUIRED 입니다. 즉, 제공되지 않으면 메서드가 호출될 때마다 새 트랜잭션이 생성됩니다 .
우리의 경우 save() 메소드를 호출할 때마다 새로운 트랜잭션이 생성되는 반면, saveAll() 을 호출 하면 하나의 트랜잭션만 생성되고 나중에 save() 에 의해 재사용됩니다 .
이 오버헤드는 앞서 확인한 성능 차이로 이어집니다.
마지막으로 일괄 처리가 활성화되면 트랜잭션 수준에서 수행되기 때문에 오버헤드가 더 커집니다.
5. 결론
이 기사에서는 Spring Data 의 save() 및 saveAll() 메소드 의 성능 차이에 대해 배웠습니다 .
궁극적으로 다른 방법보다 한 방법을 사용할지 여부를 선택하면 응용 프로그램의 성능에 큰 영향을 미칠 수 있습니다.