일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 정보처리기사실기 기출문제
- Spring
- Elasticsearch
- CloudWatch
- aws
- 코틀린 코루틴의 정석
- kotlin spring
- Java
- IntelliJ
- 기록으로 실력을 쌓자
- AI
- 공부
- PETERICA
- 정보처리기사 실기 기출문제
- kotlin coroutine
- Kubernetes
- 정보처리기사 실기
- Pinpoint
- mysql 튜닝
- kotlin
- kotlin querydsl
- CKA 기출문제
- APM
- Linux
- 오블완
- CKA
- minikube
- AWS EKS
- 티스토리챌린지
- MySQL
- Today
- Total
피터의 개발이야기
[MySQL] 중복체크를 위한 Count vs Limit vs Exists 본문
ㅁ 들어가며
ㅇ JPA를 사용 중인 프로젝트에서 중복체크 기능을 구현하면서 Exists와 Count의 성능차이를 고민하였다.
ㅇ [QueryDSL] fetchFirst()와 fetchOne()의 차이을 정리하면서 Count vs Limit vs Exists 성능 차이에 대해서 정리하였다.
ㅇ JPA exists 쿼리 성능 개선을 보고, 이해한 부분을 정리하였다.
ㅁ성능 비교
ㅇ 대량의 데이터(약 5600만 건)가 있는 테이블에서 COUNT와 EXISTS의 성능을 비교해보면 2배에 가까운 성능 차이가 나타났다.
ㅇ 데이터가 1억 건 이상으로 늘어나면 이 차이는 더욱 벌어질 것이다.
- COUNT: 9.079초
- EXISTS: 5.278초
ㅁ 원인분석
ㅇ 이러한 성능 차이의 원인은 각 쿼리의 동작 방식에 있다
- EXISTS: 첫 번째 결과에서 바로 TRUE를 반환
- COUNT: 총 레코드 수를 확인하기 위해 전체 테이블을 스캔
ㅇ 따라서 EXISTS가 COUNT보다 더 효율적으로 동작한다.
ㅁ JPA와 Querydsl에서의 문제점
ㅇ 그러나 JPA의 @Query 어노테이션과 Querydsl에서는 SELECT EXISTS 구문을 직접 사용할 수 없는 문제가 있다.
ㅇ 이로 인해 개발자들은 주로 COUNT 쿼리를 사용하게 되는데, 이는 앞서 언급한 성능 이슈를 야기한다.
ㅁ LIMIT 1을 이용한 해결책
ㅇ EXISTS의 성능 이점을 활용하기 위해 LIMIT 1을 사용하는 방법이 있다.
ㅇ 이 방법은 전체 테이블을 스캔하지 않고 첫 번째 결과만 확인하므로 EXISTS와 유사한 성능을 낼 수 있다.
ㅇ Querydsl에서는 다음과 같이 구현할 수 있다
public Boolean exist(Long bookId) {
Integer fetchOne = queryFactory.selectOne()
.from(book)
.where(book.id.eq(bookId))
.fetchFirst(); // LIMIT 1 return fetchOne != null;
}
ㅇ 이 방법을 사용하면 EXISTS와 동일한 성능 효과를 얻을 수 있다.
ㅁ 마무리
- COUNT는 EXISTS에 비해 성능 이슈가 있다.
- JPA의 @Query와 Querydsl에서는 SELECT EXISTS를 직접 사용할 수 없다.
- LIMIT 1을 사용하여 SELECT EXISTS를 대체할 수 있으며, 이는 비슷한 성능을 제공한다.
- JpaRepository의 메소드 쿼리는 내부적으로 LIMIT 1을 사용하므로 성능상 문제가 없다.
중복 체크 시 이러한 차이점을 고려하여 적절한 방법을 선택하면 효율적인 쿼리 성능을 얻을 수 있다.
ㅁ 함께 보면 좋은 사이트
ㅇ [MySQL 튜닝] EXISTS를 이용한 SQL 튜닝
ㅇ DB 데이터 존재 확인 Count vs Limit vs Exists
'Database > MySQL' 카테고리의 다른 글
[MySQL] MySQL과 Java의 SSL 연결 방법 (0) | 2024.06.17 |
---|---|
MySQL과 PostgreSQL의 차이점 (0) | 2024.04.15 |
MySQL 콘솔 접속 방법 (0) | 2024.01.18 |
[MySQL] Mysql Docker 설치, 8.0 (0) | 2023.08.22 |
[MySQL] DB 용량 확인, 테이블별 용량 확인 (3) | 2023.08.18 |