Proxy 어떻게 최적화해?
# 인프런 김영한의 자바 ORM 표준 JPA 프로그래밍 - 기본편을 개인적으로 정리한 글입니다.
정리
1.Proxy 어떻게 최적화해?
Lazy loading 과 proxy의 사용으로 해결한다.
2.어떻게 하는데?
ManyToOne , OnetoOne 과 같이 One으로 끝나는 어노테이션에(fetch = FetchType.LAZY)를 넣어준다.
3.Lazy loading이 뭐야?
Lazy Loading을 하면 연관되어 있는 값을 필요에 의해서 쓸때 SQL 쿼리가 나가 값을 가져오게하는 설정.
== 필요에 따른 sql문을 날리기 때문에 성능 Up. 유지보수령 Up
4.Eager는 왜 안써?
1. 예상못한 SQL문의 발생
2. JPQL에서 N+1 문제를 발생시킨다.
5.N+1문제가 뭐야?
"select * from User u" 쿼리를 사용할때(단순 조회 쿼리)
TeamA 에 user1 이 존재
TeamB에 user2 가 존재
한다면.
Query는
1. User find Query가 한방 나간다,
2. TeamA 를 가져오는 Query가 한방 나간다
3. TemaB 를 가져오는 Query가 한방 나간다.
select * from User u"라는 쿼리 하나를 사용했을 뿐인데 DB에는 Query가 3(N)방이 나갔다.
6.N+1 문제 해결방법은?
공통 : fetch= FetchType.LAZY로 변경한다,
1. JPQL의 fetch join을 활용한다 == 동적으로 원하는 애들을 가져온다,
2. @EntityGraph 어노테이션을 활용한다
3. batch size를 활용한다.
살펴보기
1,2. Proxy 어떻게 최적화해 + 사용해?
=>연관관계 매핑에 LAZY 사용해.
@ManyToOne(fetch = FetchType.LAZY)
3.Lazy Loding이 뭐야?
User 와 Team이 다음과 같이 설정되어 있고 Lazy loading으로 설정되어 있다면
@Entity
public class User {
@Id @GeneratedValue
private Long id;
@Column(name = "username")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
}
@Entity
public class Team {
@Id
@GeneratedValue
private Long id;
@OneToMany(mappedBy = "team")
List<User> user = new ArrayList<>();
}
User user = em.find(User.class , 1L);
코드를 사용했을때
User는 객체형태로 Team은 프록시 형태로 되어
User 쿼리는 날리지만
Team 관련 Query를 날려주지 않는다.
Team team = user.getTeam();
상태에서도 Team은 Proxy 상태!
team.getName();
하는순간
Team관련 Query를 사용해 가져온다.
4.Eager는 왜 안써?
1. 예상못한 SQL문의 발생
2. JPQL에서 N+1 문제를 발생시킨다.
List<User> users = em.createQuery("select u From User u join ", User.class)
.getResultList();
쿼리 1개만 사용했는데 Query가 N개가 나오네? = N+1문제
5.N+1문제가 뭐야?
"select * from User u" 쿼리를 사용할때(단순 조회 쿼리)
한다면.
member1 | TeamA |
member2 | TeamB |
Query는
1. User find Query가 한방 나간다.
"select * from Member' // 예시
2. TeamA 를 가져오는 Query가 한방 나간다
select * from Team where Team_id=TeamA125123 // 예시
3. TemaB 를 가져오는 Query가 한방 나간다.
select * from Team where Team_id=TeamB12314 // 예시
select * from User u"라는 쿼리 하나를 사용했을 뿐인데 DB에는 Query가 3(N)방이 나갔다.
6.N+1 문제 해결방법은?
공통 : fetch= FetchType.LAZY로 변경한다,
1. JPQL의 fetch join을 활용한다 == 동적으로 원하는 애들을 가져온다.
List<User> users = em.createQuery("select u From User u join fetch m.team ", User.class)
.getResultList();
2.@EntityGraph어노테이션을 활용한다. //추후 추가예정
3.batch size를 활용한다.//추후 추가예정