JPA와 QueryDSL을 활용할 때 성능 최적화는 필수적인 요소입니다. 잘못된 설정이나 비효율적인 쿼리는 성능 저하를 초래할 수 있습니다. 이번 포스팅에서는 QueryDSL과 JPA의 성능 튜닝 전략을 소개합니다.
1. Lazy Loading과 Fetch Join 최적화
1) Lazy Loading 기본 설정
JPA에서는 연관된 엔티티를 로딩할 때 LAZY 전략을 기본으로 설정하는 것이 성능 최적화에 유리합니다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY) // 지연 로딩 설정
private Team team;
}
2) Fetch Join 활용
Lazy Loading으로 설정하면 N+1 문제가 발생할 수 있습니다. 이를 해결하기 위해 Fetch Join을 사용할 수 있습니다.
List<Member> members = queryFactory
.selectFrom(member)
.join(member.team, team).fetchJoin()
.fetch();
💡 Fetch Join을 사용하면 연관된 엔티티를 한 번의 쿼리로 가져올 수 있습니다.
2. Batch Size 설정을 통한 최적화
1) @BatchSize 어노테이션 사용
Batch Fetch Size를 설정하면 연관된 엔티티를 IN 절을 활용하여 한 번에 가져올 수 있습니다.
@Entity
public class Team {
@OneToMany(mappedBy = "team")
@BatchSize(size = 10)
private List<Member> members;
}
2) 글로벌 설정 적용
spring.jpa.properties.hibernate.default_batch_fetch_size=100
💡 BatchSize 설정을 활용하면 N+1 문제를 줄일 수 있습니다.
3. 인덱스 활용 및 DTO 조회 최적화
1) 인덱스 설정
컬럼에 인덱스를 추가하면 검색 속도를 향상시킬 수 있습니다.
@Entity
@Table(indexes = {@Index(name = "idx_member_name", columnList = "name")})
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
}
2) DTO 조회 최적화
엔티티가 아닌 DTO를 사용하여 필요한 데이터만 조회하면 성능을 개선할 수 있습니다.
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class,
member.name,
member.age))
.from(member)
.fetch();
💡 DTO 조회를 활용하면 불필요한 데이터를 로딩하지 않도록 최적화할 수 있습니다.
4. 페이징 최적화 및 캐싱 적용
1) 페이징 쿼리 최적화
fetch()와 count()를 분리하여 성능을 개선할 수 있습니다.
JPAQuery<Member> query = queryFactory.selectFrom(member);
List<Member> content = query
.offset(0)
.limit(10)
.fetch();
long total = queryFactory
.select(member.count())
.from(member)
.fetchOne();
2) Redis 캐싱 적용
반복적인 조회는 Redis를 활용하여 캐싱할 수 있습니다.
@Cacheable(value = "memberCache", key = "#id")
public Member findMember(Long id) {
return memberRepository.findById(id).orElse(null);
}
💡 페이징 및 캐싱을 적용하면 성능을 더욱 개선할 수 있습니다.
결론
QueryDSL과 JPA를 사용할 때 성능을 최적화하는 방법은 다음과 같습니다.
✅ Lazy Loading을 기본으로 설정하고 Fetch Join 활용
✅ Batch Fetch Size 설정으로 N+1 문제 해결
✅ 인덱스를 활용하여 검색 속도 개선
✅ DTO 조회를 통해 불필요한 데이터 로딩 방지
✅ 페이징 최적화 및 캐싱을 활용한 성능 개선
'BackEND > Java' 카테고리의 다른 글
Spring Boot에서 REST API 설계 및 개발하기 (0) | 2025.04.06 |
---|---|
실제 프로젝트에서 QueryDSL과 캐싱을 활용한 최적화 전략 (0) | 2025.04.05 |
QueryDSL을 활용한 동적 쿼리 작성 및 성능 개선 (0) | 2025.04.03 |
JPA의 기본 조회 성능 최적화 기법 (0) | 2025.04.02 |
JPA와 QueryDSL 소개 및 비교 (0) | 2025.04.01 |