-
[리팩토링 보고서] JPA 쿼리 성능 최적화Back End/리팩토링 보고서 2022. 3. 5. 02:27
이 포스팅은 삽질 경험을 바탕으로 정리하였습니다.
더 나은 옵션이 있을 시 계속 업데이트 됩니다.목차
1. Query(Read) Rule
2. 성능개선 내역
Query RULE.
1. xToMany 변수를 가지지 않은 엔티티
JPA QueryMethod(Interface-Projection, UnderScore Join)로 Query한다.
- API 스펙변화가 Repository까지 전파되지 않아 코드 재사용성이 좋아진다.
- 원하는 필드만 select하여 네트워크 비용을 소폭 감소시킨다.
2. xToMany 변수를 가진 엔티티
JPA의 Fetch Join 기능을 이용한다. (QueryDSL, @EntityGraph, @BatchSize)
2-1. xToMany 변수가 2개이상 일때
xToOne 을 먼저 모두 FetchJoin 한 후 Many쪽은 LazyLoading 한다.
Many 2개이상을 FetchJoin 할 경우 하이버네이트가 어느 기준으로 엔티티에 Fetch 해야할지 혼란스러워 해 데이터 부정합이 생길 수 있다.
2-2 xToMany 변수가 1개 일때
바로 FetchJoin을 걸어도 된다.
하지만 코드 일관성을 위해 2-1과 같이 구성하는게 옳다고 생각한다.Query가 한번 더 나가긴 하지만, 큰 성능차이는 없다. (핵심은 IN절에 있으므로)
성능개선 내역
1. OneToMany 에서 fetchJoin(BatchSize) VS 같은로직 직접구현
FetchJoin 승
비즈니스 로직에따라 DTO를 조회할 때,
@BatchSize
의 기능을 꼭 수동으로 구현해야 할 경우를 제외하고는 위의QueryRule
를 따르자- 1000개의 User, 각 User당 100개의 Item 으로 테스트를 기준으로 직접구현이 1.5배 더 시간이 걸린다.
(DTO 변환 오버헤드 제외) - 필자 직접구현 코드(GitHub)
- 칼럼갯수가 많지 않은 엔티티들은 fetchJoin으로 조회하고 DTO로 변환하는게 성능적으로 더 이득이다.
2. Spring Data JPA Repository 반환형 Slice VS Page
Slice 승
Slice 는
limit+1
로 다음 레코드가 있는지 체크하고, Page 는집계쿼리(COUNT)
로 다음레코드를 체크하여 쿼리문이 하나 더 발생한다.3. @JoinColumn의 referencedColumn 은 사용하지 말자
객체 설계관점(DB아님)에서도, 성능적으로도 좋지 않다.
- 비식별관계(PK로 연결된 관계는 제외)는 ORM으로 매핑하는 것은 성능적으로 매우 좋지않다.
- ORM 입장에서는 모든 연관관계는 PK를 보도록 설계하는 것이 좋은 설계이다.
- PK로 연결되지 않은 비식별관계는 따로 문서화나 어노테이션으로 표시해둔다.
4. @Inheritance(strategy=JOINED) 에서 슈퍼클래스 필드만 Query하기
조인전략에서 Spring Data JPA는 슈퍼클래스 조회시 하위클래스를 조인하여 가져온다.
쿼리성능에서 조인과 where 절(인덱스 설정)의 지분이 매우크다.
그러하므로 이러한 쓸모없는 조인을 줄이는건 성능적 기여가 크다.
728x90'Back End > 리팩토링 보고서' 카테고리의 다른 글
[리팩토링 보고서] 서버과부하 방지를 위한 Batch 처리 (0) 2022.03.05 [리팩토링 보고서] 일급 컬렉션의 적용 (0) 2022.03.04 [리팩토링 보고서] API와 Repository 의존성 제거하기 (DTO-Repository 의존성 제거) (0) 2022.03.04 [리팩토링 보고서] 레이어간 의존성 개선 (0) 2022.03.04 [개발노트] PocketMark 개발노트 (0) 2022.03.03