[JPA] N+1 문제
·
Spring Framework/JPA
N+1 문제란 ORM 사용 시 발생하는 대표적인 성능 이슈부모 엔티티를 조회하는 1번의 쿼리 후, 각 부모마다 연관된 자식 엔티티를 조회하는 N번의 추가 쿼리가 실행되는 현상예시: 100개의 게시물과 댓글 있을 때게시글 전체 조회: 1번 + 각 게시글의 댓글 조회: 100번 ⇒ 총 101번의 쿼리가 실행모든 정보를 한 번의 쿼리로 가져오지 못하고 추가 쿼리로 인해 성능 이슈가 발생한다.문제 상황게시물(Post), 댓글(Comment) 엔티티가 있다.(이외의 테이블은 없다고 가정)게시물 목록 조회 시 각 게시물의 댓글 갯수를 함께 조회하고 싶다.@Entity@Table(name = "post")@NoArgsConstructor(access = AccessLevel.PROTECTED)@Getterpublic..
[JPA] 5개 데이터가 4+1개 쿼리로 나누어지다.
·
Spring Framework/JPA
Spring Data JPA의 saveAll()로 대량 데이터를 삽입할 때 예상과 다른 SQL이 실행되는 것을 발견누가 배치 쿼리를 어떻게, 왜 분할하는지 코드를 찾아본 과정예상 vs 실제 쿼리 실행5개의 프로젝트 데이터를 saveAll()로 저장했을 때:// 5개 엔티티를 한 번에 저장List projects = generateProjects(5);projectRepository.saveAll(projects);예상한 쿼리:# 예상했던 쿼리INSERT INTO project (title,id) VALUES ($1,$2),($3,$4),($5,$6),($7,$8),($9,$10);# 실제 실행된 쿼리# - 4개 + 1개로 분할됨INSERT INTO project (title,id) VALUES ($1,$..
[JPA] Batch Insert
·
Spring Framework/JPA
대량의 데이터를 데이터베이스에 삽입하는 작업은 자주 접할 수 있는 이슈Spring Boot, PostgreSQL을 사용할 때 대량 데이터 삽입 성능을 최적화하는 방법과 실험을 통해 비교 분석JDBC Template을 직접 사용한 배치 삽입이 JPA Repository 방식보다 최대 76.3% 더 빠른 성능을 보였다.PostgreSQL의 `reWriteBatchedInserts` 옵션 활성화만으로도 상당한 성능 향상을 얻을 수 있었다.실습Spring Boot, Spring Data JPA, PostgreSQL 환경에서 대량 데이터를 삽입할 때 사용할 수 있는 여러 방법의 성능을 비교개별 엔티티 저장(Repository.save())엔티티 컬렉션 저장(Repository.saveAll())JDBC 템플릿을 ..
[JPA] orphanRemoval, CasecaseType.REMOVE
·
Spring Framework/JPA
orphanRemoval과 casecade는 @OneToMany에서 삭제 동작을 제어하는 두 가지 옵션이다. orphanRemoval=true, CascadeType.REMOVE 두 옵션 모두 부모-자식 관계에서 자식 엔티티를 삭제하는 설정이지만 차이가 있다.casecadecasecade는 부모 엔티티의 상태 변화가 자식 엔티티에 전파되도록 설정하는 옵션으로 부모 엔티티가 생성/수정/삭제 될 때 자식 엔티티에도 부모 엔티티를 따라 데이터베이스에 생성/수정/삭제되록 설정한다. 이 옵션에 지정할 수 있는 다양한 CascadeType이 있다.PERSIST: 비영속 상태의 부모 엔티티를 영속상태로 변경할 때 자식 엔티티도 영속 상태로 변경MERGE: 준영속 상태의 부모 엔티티를 영속상태로 변경할 때 자식 엔티티..