어느날 문득
무작정 스프링을 쓰는 것보단,
왜 쓰는지에 대해 생각을 해보면서 코딩을 하면 좋을 것 같다는 생각이 들었다.
난 실무를 경험한 적이 없으므로,
실무를 하며 "아 이렇게 해야겠구나"라는 체감을 한 적이 없다.
그래서 어쩔 수 없이 아쉽지만 이론상으로라도 접해야겠다.
(그냥 아무 생각 없이 하는 것보단 나을 것 같음)
제일 먼저 찾아본 자료는
[REST API를 개발할 때, 성능 최적화를 하는 방법들]에 대해서다.
제일 중요한 건 엔티티를 웹에 노출해서는 안 된다고 한다.
그럼 어떻게 해야 할까?
→ 간단하다. 별도의 DTO를 만들어, 거기서 조회한 엔티티를 넣어서 반환해주면 된다.
문제점
JPA로 애플리케이션을 개발할 때 발생하는 다양한 성능 문제와 해결 방안을 알아보자.
N + 1 문제
JPA로 애플리케이션을 개발할 때 성능상 가장 주의해야 하는 것이 N + 1 문제다.
처음 실행한 SQL의 결과 수만큼 추가로 SQL을 실행하는 것을 N + 1 문제라 한다.
즉시 로딩은 JPQL을 실행할 때 N + 1 문제가 발생할 수 있다.
지연 로딩과 N + 1
즉시 로딩 시나리오를 지연 로딩(fetch = FetchType.LAZY)으로 변경해도 N + 1 문제에서 자유로울 순 없다.
이처럼 N + 1 문제는 즉시 로딩과 지연 로딩일 때 모두 발생할 수 있다.
조회 API의 성능 최적화를 위해
N + 1 문제를 피할 수 있는 다양한 방법을 알아보자.
1. 페치 조인 (fetch join)을 사용해라
N + 1 문제를 해결하는 가장 일반적인 방법은 페치 조인을 사용하는 것이다.
페치 조인은 SQL 조인을 사용해서 연관된 엔티티를 함께 조회하므로,
N + 1 문제가 발생하지 않는다.
2. 엔티티를 웹에 노출해서는 안된다.
3. 연관 관계일 때, 한 곳을 @JsonIgnore 처리해야 한다. (엔티티를 직접 노출할 때)
4. 읽기 전용 쿼리의 성능 최적화
읽기 전용 트랜잭션 사용
@Transactional(readOnly = true)
→ 이렇게 하면 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않는다.
따라서 트랜잭션을 커밋해도 영속성 컨텍스트를 플러시하지 않는다.
영속성 컨텍스트를 플러시하지 않으니,
엔티티의 등록, 수정, 삭제는 당연히 동작하지 않는다.
쿼리 방식 선택 권장 순서
- 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
- 필요하면 페치 조인으로 성능을 최적화 한다. 대부분의 성능 이슈가 해결된다.
- 그래도 안 되면, DTO로 직접 조회하는 방법을 사용한다.
- 최후의 방법은 JPA가 제공하는 네이티브 SQL이나, 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.
자세한 건 여기에 적어놓았다.
출처
- https://heewon26.tistory.com/173
- https://www.inflearn.com/blogs/1884
- https://oingdaddy.tistory.com/402
- https://ummmmchicken.tistory.com/entry/JPA-%ED%99%9C%EC%9A%A9-2-API-%EA%B0%9C%EB%B0%9C%EA%B3%BC-%EC%84%B1%EB%8A%A5-%EC%B5%9C%EC%A0%81%ED%99%94
'Spring > 그 외' 카테고리의 다른 글
[Spring] 서블릿 필터 & 핸들러 인터셉터 (0) | 2023.02.08 |
---|---|
[Spring] @SpringbootApplication의 원리 (0) | 2023.01.27 |
[Spring] 왜 스프링을 쓰는가? (특징 & 계층 구조) (0) | 2023.01.23 |
Spring(스프링) 주요 어노테이션 정리 (0) | 2023.01.22 |
Dto, Controller, Service (0) | 2023.01.07 |