<TIL> 104. 쿼리 최적화

YUJIN LEE·2023년 4월 25일
0

개발log

목록 보기
97/149

DB 조회 쿼리 최적화

Projection을 통해 필요한 값만 가져오기

전체 필드가 아닌 필요한 필드만 받아오기

  • 적용 전: SELECT * FROM User;
  • 적용 후: SELECT username, profileImageUrl FROM User;
List<UserProfile> findById(Long userId);

위의 코드는 repository 코드이다.
밑의 인터페이스를 통해 User Entity 안에 username과 profileImageUrl이 있으면,
위의 SQL문처럼 적용해서 필요한 값만 가져올 수 있게 해준다.

public interface UserProfile {
	String getUsername();
    String getProfileImageUrl();
}

하이버네이트 @BatchSize

하이버네이트에서 제공하는 어노테이션을 사용하면,
연관된 엔티티를 조회할 때 지정한 사이즈 만큼만 조회한다.
(SQL IN절 사용)

@BatchSize(size = 5)
@OneToMany(mappedBy = "member", fetch = FetchType.EAGER)
private List<Order> orders = new ArrayList<Order>();

즉시로딩으로 조회시 반복만큼 Orders 엔티티를 조회해야하는데,
BatchSize 설정으로 5개씩 끊어서 조회된다.
-> 6번째 데이터를 사용할 때 추가 쿼리 실행
select * from orders where member_id in('~', '~', '~', '~', '~');

JPA는 1차 캐시, 영속성 컨텍스트라는 이름으로 변경감지를 통해 얻는 장점이 많다.
이러한 장점을 얻기 위해서는 많은 인스턴스들이 메모리에 할당되어야하는 이슈가 있다.
이런 이슈를 해결하고자 읽기 전용으로 엔티티를 조회하는 경우 메모리 사용량을 최적화해야한다.

읽기 전용 쿼리 힌트 적용

하이버네이트 전용 힌트인 readOnly 적용(영속성 컨텍스트 관리에서 제외)

TypeQuery<Order> query = em.createQuery("select o from Order o", Order.class);
query.setHint("org.hibernate.readOnly", true);

Query DSL - setHint
내가 작성한 쿼리를 DB에서 수행할 때, 로그를 남길 때 빨리 수행할 수 있는 힌트, 이것에 대한 네임을 달 수있는 힌트.
setHint를 통해 하이버네이트 리드홀이라는 옵션을 true로 설정하면 영속성 컨텍스트 관리에서 제외.

읽기 전용 트랜잭션 사용

비슷한거로 @transactional readonly true가 있는데,
이거는 transactional을 읽기모드로 적용.
강제로 플러시를 호출하지 않는 이상 플러시 발생x
그러므로 자동으로 플러시되며 수행되는 무거운 로직들이 실행되지 않아 성능 향상

트랜젝션 밖에서 읽기

profile
인정받는 개발자가 되고싶습니다.

0개의 댓글