[2020우아콘]수십억건에서 QUERYDSL 사용하기 정리

Yoojin Jeong·2021년 2월 7일
0

extends/implements 사용하지 않기

JPAQueryFactory만 있으면 Querydsl의 모든 기능을 사용할 수 있다.

동적쿼리는 BooleanExpression

어떤 쿼리인지 예상하기 어렵다

Querydsl의 exist 메소드 금지

select를 사용할 때 (원하는 데이터가 있는지 판단할 때) exists가 count보다 빠르다. 스캔 대상이 앞에 있을 수록 더 심한 성능차이 발생.

exists가 빠른 이유는 조건에 해당하는 row 1개만 찾으면 바로 쿼리를 종료하기 때문임.

limit 1로 조회를 제한함(조회결과가 없으면 null이란 조건도 추가해야함)

Cross Join 회피

묵시적 join으로 Cross Join 발생 (일부의 DB는 이에 대해 어느정도 최적화가 지원됨)
Hibernate 이슈라서 Spring Data JPA도 동일하게 발생
명시적 Join으로 Inner Join 발생

Entity 보다는 Dto를 우선 사용

Entity 조회시 Hibernate 캐시 불필요한 컬럼 조회 OneToOne N+1 쿼리 등 단순 조회 기능에서는 성능 이슈 요소가 많다.

  • Entity 조회를 쓰는 경우
    실시간으로 Entity 변경이 필요한 경우
  • Dto 조회를 쓰는 경우
    고강도 성능 개선 or 대량의 데이터 조회가 필요한 경우

조회컬럼 최소화하기

Select 컬럼에 Entity 자제

Group By 최적화

Filesort가 발생할 때, 우회가 필요함.
ordey by null는 사용할 수 없기 때문에 조건 클래스를 생성해서 적용한다.

커버링 인덱스

커버링 인덱스란 쿼리를 충족시키는데 필요한 모든 컬럼을 갖고있는 인덱스
select /where / order by / group by 등에서 사용되는 모든 컬럼이 인덱스에 포함된 상태
NoOffset 방식과 더불어 페이징 조회 성능을 향상시키는 가장 보편적인 방법

Cluster Key(PK)를 커버링 인덱스로 빠르게 조회하고, 조회된 Key로 Select 컬럼들을 후속 조회한다.
결과적으로 기존 커버링 인덱스와 거의 비슷한 성능을 보여줌.

일괄 Update 최적화

DirtyChecking방식

트랜잭션 내부에 있을 때 Entity를 조회해서 해당 Entity 값을 자동으로 변경하는 방식.
무분별한 DirthChecking을 이용할 시 성능 떨어짐.
실시간 비즈니스 처리, 실시간 단건 처리시 필요함

Querydsl.update

대량의 데이터를 일괄로 Update 처리시 필요함.

Bulk Insert

0개의 댓글