🧑💻
이번 포스팅에서는 즉시로딩과 지연로딩에 대해 이야기해보고자 한다.
🧑💻 즉시로딩과 지연로딩
데이터베이스에서 연관 엔티티를 불러오는 방식에 따라 즉시로딩과 지연로딩으로 나뉜다.
💡 즉시로딩
즉시로딩은 어떤 엔티티를 조회할 때, 연관관계가 맺어져 있는 다른 엔티티까지 모두 조회하는 방식이다.
💡 지연로딩
지연로딩은 즉시로딩과 다르게, 엔티티가 필요하기 전에는 해당 엔티티를 미리 조회하지 않는 방식을 말한다.
🧑💻 언제 어떠한 방식을 사용해야 하는가?
💡 즉시로딩
즉시로딩은 연관된 엔티티를 전부 조회하는 방식이기 때문에 연관된 엔티티의 데이터가 필요한 경우에 사용할 수 있다. 하지만, 모든 연관된 데이터를 조회하기 때문에 초기 로딩 시간이 길고, 메모리에 과부하가 올 수 있다는 단점이 있다.
💡 지연로딩
지연로딩은 연관된 엔티티를 실제로 필요할 때 조회하는 방식이기 때문에 연관된 데이터가 사용되지 않는 경우에 사용할 수 있다. 필요한 엔티티만을 조회하기 때문에 메모리 효율성이 좋지만, JPA에서 항상 거론되는 N+1 문제가 발생할 수 있다는 것이 단점이다.
🧑💻 N+1 문제
N+1 문제가 뭘까? 기본적으로 N+1 문제는 지연로딩 방식을 사용할 때 발생할 수 있는 문제이다.
N+1은 어느 엔티티를 조회할 때 연관되어 있는 엔티티에 대해 추가적인 쿼리가 실행되어 1번 실행할 것은 N번 더 실행하게 되는 걸 이야기한다.
예시로, 일대다 연관관계를 가진 User, Video 엔티티가 있다 가정해 보겠다. 유저 객체 1개는 여러 동영상 객체를 가질 수 있는데, 다음과 같은 코드에서 N+1 문제가 발생한다.
// 모든 유저를 조회하는 쿼리 (1번 실행)
List<User> users = userRepository.findAll();
// 각 유저의 동영상을 조회 (유저의 수만큼 쿼리 실행)
for (User user : users) {
List<Video> videos = user.getVideos(); // 여기서 각 유저마다 쿼리 실행
}
모든 유저를 조회하는 쿼리를 실행함으로써 1번의 쿼리가 실행된다. 이때, 조회된 유저의 수가 만약 5명이라면 각 유저의 동영상을 조회하기 위해 5번의 쿼리가 추가적으로 실행된다.
모든 유저를 조회하는 쿼리(1번의 쿼리), 각 유저에 대한 동영상을 조회하는 쿼리(N번 -> 유저의 수). 이것이 N+1이다.
🧑💻 어느 방식을 사용해야 하는가?
위에서 각 방식의 차이점과 장단점을 알아보았다. 실무에서는 무조건 지연 로딩을 사용한다고 한다. 즉시 로딩은 성능 최적화가 어렵기 때문이라고 한다.
💡 즉시 로딩이 성능 최적화가 어려운 이유
- 조회해야 할 데이터셋이 많을 때 즉시 로딩은 치명적이다.
- 한 번에 많은 데이터들을 메모리에 올리기 때문이다.
- 불필요한 데이터까지 전부 가져오기에 메모리에 좋지 못하다.
- 조인을 통해 연관된 엔티티의 데이터까지 가져오기 때문에 이 과정에서 쿼리가 복잡해지고, 이로 인해 DB 성능이 저하될 수 있다고 한다.
💡페치 조인 활용
지연 로딩을 사용하면 N+1 문제가 발생할 수 있는데, 이는 페치 조인을 통해 해결이 가능하다.
즉, 일반적으로 엔티티에 대해서 지연 로딩을 설정하여 연관된 엔티티의 데이터까지 조회되지 않게 하고, 필요한 경우에 페치 조인을 하여 즉시 로딩과 같은 효과를 볼 수 있게 하는 것이다.
@Query("SELECT u FROM User u JOIN FETCH u.videos")
List<User> findAllWithVideos();
@Query("SELECT u FROM User u JOIN FETCH u.videos WHERE u.id = :userId")
User findUserWithVideos(@Param("userId") Long userId);
🧑💻
즉시로딩과 지연로딩에 대해 알아보았다. N+1 문제는 굉장히 유명하고 많이 언급되는 것 중 하나인데, 글로 다시 정리하면서 좀 더 정확히 알 수 있어서 좋았다.
'TIL' 카테고리의 다른 글
단일 책임의 원칙 (누구의 책임인가) (0) | 2024.10.08 |
---|---|
함께 자라기 - 애자일로 가는 길 (2) | 2024.08.30 |
Spring Batch란? (0) | 2024.07.01 |
Annotation이란 무엇인가 (1) | 2024.06.30 |
MVC 모델이란? (0) | 2024.06.25 |