본문 바로가기
스프링과 JPA 기반 웹 어플리케이션 개발/8부 검색 및 첫 페이지

79. N+1 Select 문제 해결

by Backchus 2020. 5. 17.

left (outer) join + fetchJoin + distinct로 해결.

left (outer) join

  • 첫번째(left) 테이블에 연관 관계가 있는 모든 데이터 가져오기. 연관 데이터가 없으면 null로 채워서라도..
  • 첫번째 테이블 컬럼만 본다면 중복 row 발생

fetchJoin

  • join 관계의 데이터도 같이 가져온다.

distinct

  • 중복 제거

홈 화면에서 스터디를 조회할 때 Study엔티티만을 조회했기 때문에 Study하나당 Study관련 쿼리, Tag관련 쿼리, Zone관련 쿼리, 멤버 관련쿼리 이렇게 여러번 쿼리가 나가게 된다. 이것을 최적화 시키기 위해 findByKeword를 수정하여 Study조회시 Study와 연관된 tags, zones, member를 같이 조회하는 쿼리를 날리기위해 최적화를 시켜 준다.

package me.weekbelt.studyolle.modules.study;

public class StudyRepositoryExtensionImpl extends QuerydslRepositorySupport implements StudyRepositoryExtension{

    // .......

    @Override
    public List<Study> findByKeyword(String keyword) {
        QStudy study = QStudy.study;
        JPQLQuery<Study> query = from(study).where(study.published.isTrue()
                //.........
                .leftJoin(study.tags, QTag.tag).fetchJoin()                  // tag 엔티티 fetch
                .leftJoin(study.zones, QZone.zone).fetchJoin()               // zone 엔티티 fetch
                .leftJoin(study.members, QAccount.account).fetchJoin()       // members fetch
                .distinct();                                                 // 중복 제거
        return query.fetch();
    }
}

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#

 

스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런

이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습�

www.inflearn.com