[스프링] JPA 성능 튜닝

스프링 애플리케이션에서 JPA를 사용하다 보면 종종 성능 이슈에 부딪힐 수 있습니다. 이러한 문제는 쿼리 최적화, 캐싱 전략, 연관 관계 로딩 방식 등을 조정하여 해결할 수 있습니다. 이번 블로그에서는 JPA 성능 튜닝을 위한 몇 가지 팁을 제공하겠습니다.

1. 쿼리 최적화

JPA에서는 쿼리가 성능에 미치는 영향이 매우 큽니다. Entity 클래스에 @EntityGraph나 @NamedEntityGraph 애노테이션을 사용하여 필요한 연관 관계를 미리 로딩하거나, @javax.persistence.NamedQuery나 @Query 애노테이션을 사용하여 성능에 영향을 주는 쿼리를 최적화할 수 있습니다.

@Entity
@NamedEntityGraph(name = "author-books-entity-graph", attributeNodes = @NamedAttributeNode("books"))
public class Author {
    // ...
}

@Repository
public interface AuthorRepository extends JpaRepository<Author, Long> {
    @EntityGraph("author-books-entity-graph")
    Optional<Author> findById(Long id);
}

2. 캐싱 전략 적용

데이터베이스 쿼리 수를 줄이기 위해 JPA 캐시 기능을 활용할 수 있습니다. @Cacheable 애노테이션을 사용하여 엔티티의 조회 결과를 캐시하고, @Transactional(readOnly = true)를 사용하여 읽기 전용 트랜잭션으로 데이터베이스 부하를 줄일 수 있습니다.

@Entity
@Cacheable
public class Book {
    // ...
}

@Service
@Transactional(readOnly = true)
public class BookService {
    // ...
}

3. 연관 관계 로딩 방식 설정

연관 관계를 적절히 로딩하는 것도 성능 튜닝의 핵심입니다. fetch=FetchType.LAZY 옵션을 사용하여 필요한 경우에만 연관 관계를 로딩하고, @EntityGraph 애노테이션을 사용하여 한 번에 모든 연관 관계를 로딩할 수 있습니다.

@Entity
public class Author {
    @OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
    private List<Book> books;
    // ...
}

이런 방식으로 JPA의 성능을 최적화할 수 있습니다. 성능 튜닝이 어려운 경우에는 Hibernate의 stats 기능을 활용하여 쿼리 실행 횟수와 수행 시간을 모니터링하고, 데이터베이스의 인덱스를 적절히 설계하여 성능을 향상시킬 수 있습니다.

참고문헌: