Batch 처리하기 DB에는 수백만건의 데이터를 한번에 처리해야하는 상황도 올 수 있다. 이럴 경우 가장 조심해야 하는 부분은 "메모리 부족 오류"이다. JPA는 영속화를 하게 되며 영속성 컨텍스트의 1차 캐시와 쓰기지연 저장소에 SQL 쿼리를 저장한다. 수백만건을 한방에 처리한다고 하면, 수백만건에 대한 엔티티 + 쿼리가 계속 메모리 상에 저장되고 있는 것이다. 이것은 메모리 부족 오류 문제를 야기한다. 이런 문제점을 해결 하기 위해서는 "나눠서 처리"를 해야한다. 나눠서 DB에 값을 밀어넣거나 가져오고, 필요한 연산을 하고 영속성 컨텍스트를 초기화해준다. 그리고 다시 또 나눠서 처리를 하는 방식이다. 이 경우, 메모리 부족 오류는 개선할 수 있지만 DB 커넥션을 자주 타게 되면서 동작 속도 관점에서는..
N+1문제 N+1은 1번의 쿼리만 의도를 했었는데, 실제 쿼리가 실행되는 시점에서는 쿼리가 N개가 더 나가는 문제다. 이 문제가 일어나게 되면 당연한 이야기지만, 의도하지 않은 쿼리가 나가게 되면서 급격히 성능이 안 좋아지는 것을 느낄 수 있다고 한다. 공부하는 입장에서는 와닿지 않지만, DBA분에게 바로 이상하다고 연락이 온다고 한다. N+1 문제 발생 상황 N+1 문제는 주로 다대일 연관관계의 엔티티를 여러 개를 불러왔을 때 생기는 것 같다. 이를테면 위와 같은 상태에서 자주 발생하는 것으로 보인다. 코드로 하나하나 살펴보려고 한다. 먼저 셋팅 코드를 공유한다. Team teamA = new Team(); teamA.setName("teamA"); em.persist(teamA); Team teamB..
Colletion Join이란? Collection Join은 일대다 관계에서의 Join으로 편리하게 이해하면 된다. 위의 그림을 예로 들어보자. Member Table과 Order Table은 One To Many의 연관관계를 가진다. 이 연관관계에서 Member를 기준으로 Order를 Join 한다고 생각해보자. Member는 Many인 Order를 객체 상태로 가지고 있기 때문에 Collection 형태로 보관하고 있다. 따라서 One을 기준으로 Many를 Join하기 때문에 Collection Join이라고 한다. Collection Join 시 페이징 불가능 Collection Join 시, 치명적인 단점이 발생한다. 바로 페이징이 불가능하거나, 가능하더라도 정합성이 떨어진다는 것이다. 위의 상..
일대다 Join (Collection Join) 일대다 연관관계를 가지는 엔티티들이 있다고 가정해보자. 이 때, 'One'을 기준으로 "Many"를 Join하는 경우를 생각해보자. One은 말 그대로 하나다. Many는 말 그대로 여러개다. 따라서 One + Many를 Join할 경우, 각 엔티티의 Row 갯수가 맞지 않는다. DB는 이 때, Many의 Row 수를 기준으로 One의 Row를 맞춘다. List findMember = queryFactory.selectFrom(member) .join(member.orderList, order) .fetch(); 예를 들어 위처럼 일대다 쿼리를 보낸다고 해보자. 그렇다면 DB 단의 테이블은 어떻게 만들어질까? DB 테이블은 member와 order를 Ord..
JPA 일대다 연관관계 → DB 반영은? JPA 일대다 연관관계에서 DB 반영은 어떻게 일어날까? '일대다' 연관관계의 의미처럼 '일'은 테이블에 1개만 저장된다. '다'는 테이블에 여러개가 저장된다. 즉, '일'의 PK를 FK로 가지는 여러 개의 '다'가 만들어지고 각각 저장된다. 아래 예시를 통해 확인해본다. Member Entity @Entity @Data @ToString(of = "name") public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String name; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, fetc..