인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

구슬탈출님의 프로필 이미지
구슬탈출

작성한 질문수

jpa 질문입니다

작성

·

134

0

현재 jpa 와 스프링 부트를 사용하여 브롤스타즈 친구 찾기 웹 사이트를 만들고있습니다. 

물어보고 싶은게 있는데요 

현재 구조는 이런데요 저의 브롤스타즈 친구찾기 웹사이트에 메인 화면 에서는 게시글을 등록합니다

하나의 게시글에 필요한 값들은

  • post엔티티의 (메모,작성일)

  • 유저엔티티의 (해시태그,성별,나이 그룹,총 트로피)

  • 유저 브롤러 엔티티의 (트로피 갯수)

  • 브롤러 엔티티의 (이름)

아래 사진은 여러개의 게시글이있는 메인 화면입니다.

제가 구현한 방법은 fetch join 을 사용해서 구현은 하긴 했는데 여기서 페이징 처리 까지 해야 해서 성능상 당연히 문제가 생길거같아서 질문드립니다.

public List<Post> findPostsWithBrawlers(int page, int size) {
        String queryStr = "SELECT p FROM Post p " +
                "JOIN FETCH p.user u " +
                "JOIN FETCH u.userBrawlers ub " +
                "JOIN FETCH ub.brawler";

        TypedQuery<Post> query = em.createQuery(queryStr, Post.class);

        // 페이징 처리
        query.setFirstResult(page*size);
        query.setMaxResults(size);

        return query.getResultList();
    }

테이블을 다시 설계해야 할까요? 아니면 fetch 조인 보다 더 좋은 방법이있을까요?

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.
구슬탈출님, JPA를 사용하여 fetch join과 페이징 처리를 같이 사용하면 성능상의 문제가 발생할 수 있습니다. 이유는 fetch join이 데이터베이스의 모든 데이터를 한 번에 가져오는 특성이 있기 때문입니다. 따라서 대량의 데이터를 처리할 때는 성능상의 이슈가 생길 수 있습니다. 이런 경우에는 아래의 몇 가지 대안을 고려해 볼 수 있습니다:

  1. Batch Size 조정: fetch join을 사용할 때 batch size를 조정하면 한 번에 가져오는 데이터의 양을 줄일 수 있습니다. 이를 통해 메모리 사용량을 줄이고 성능을 개선할 수 있습니다.

  2. Entity Graph: @EntityGraph를 사용하면, 필요한 연관 관계만 선택적으로 fetch할 수 있습니다. 이를 통해 불필요한 데이터 로드를 줄이고 성능을 개선할 수 있습니다.

  3. 분리된 쿼리 사용: fetch join의 여러 엔티티를 가져오는 대신, 각 엔티티를 분리된 쿼리로 가져온 후 코드 내에서 조합할 수도 있습니다. 이는 보통 ‘N+1’ 문제를 완화하는 데 효과적이지만 복잡한 논리가 필요한 경우도 있습니다.

  4. Projection 사용: 프로젝트에 필요한 데이터만 선택적으로 가져오고, 직접 Dto에 바인딩해 가져오는 방법입니다. 이것은 네이티브 쿼리를 작성하고 그대로 객체에 매핑하는 방법으로 사용할 수 있습니다.

  5. Query Hint 사용: JpaRepository@QueryQueryHint를 사용하여 페치 전략을 최적화할 수 있습니다.

최적의 방법은 애플리케이션 및 데이터베이스의 특성에 따라 다를 수 있으므로 여러 방법을 시도해 보며 성능을 테스트해 보는 것이 좋습니다. 필요하다면 구조적인 설계 변경도 고려해 볼 수 있습니다.

자세한 문서 및 예시는 Spring Data JPA - Reference Documentation에서 확인하실 수 있습니다.

구슬탈출님의 프로필 이미지
구슬탈출

작성한 질문수

질문하기