인덱스 관련 질문 있습니다.
56
投稿した質問数 4
안녕하세요. 인덱스를 활용한 조회 성능 개선을 공부하던 중 궁금한 점이 생겨 질문드립니다.
현재 저는 OFFSET 기반 pagination을 사용하는 서비스를 개발하고 있으며, 다음과 같은 환경에서 성능 테스트를 진행했습니다.
데이터: 약 1,000만 건
서버: EC2 t3.small
DB: RDS t4g.micro
k6 vus100
1. 문제 상황
초기에는 OFFSET 제한 없이 마지막 페이지까지 이동 가능하도록 구현했습니다.
하지만 데이터가 1,000만 건 수준으로 증가하자, 깊은 페이지로 갈수록 조회 속도가 급격히 느려지는 문제를 확인했습니다.
2. 고민 및 제약
일반적으로 이 문제는 Keyset Pagination(커서 기반)으로 해결하라고 많이 알려져 있습니다.
하지만 제 서비스는
👉네비게이션 바를 통한 페이지 직접 이동 (ex. 1, 10, 100 페이지 클릭)
이 필요하기 때문에 Keyset 방식만으로는 요구사항을 만족시키기 어렵다고 판단했습니다.
3. 적용한 개선 방법
다음과 같은 방식으로 성능 개선을 진행했습니다.
OFFSET 최대 범위를 제한 (최대 10,000 페이지 / OFFSET 100,000)
커버링 인덱스 적용
조회 방식 개선
먼저 ID만 조회 → 이후 필요한 10건만 상세 조회
전체 게시글 수(count)는 캐싱 처리
4. 성능 개선 결과
[Page 10]
avg: 1.4s → 700ms
p95: 4.5s → 1.8s
[Page 100]
avg: 17s → 1.18s
p95: 24s → 3.3s
[Page 1000]
avg: 32.1s → 1.7s
p95: 59s → 4.27s5. 추가 제약사항
로그인 사용자와 비로그인 사용자의 조회 결과가 다름
(사용자별 구독 게시글이 포함됨)따라서 캐시는 비로그인 사용자에만 적용
위 성능 수치는 로그인 사용자 기준
6. 현재 고민
위와 같이 개선했지만,
👉 여전히 성능이 충분하지 않다고 느끼고 있습니다.
특히 궁금한 점은 다음과 같습니다.
7. 질문
OFFSET 기반 pagination을 유지하면서
👉추가로 성능을 개선할 수 있는 방법이 있을까요?다음과 같은 방법들을 고려했는데, 방향성이 맞는지 궁금합니다.
RDS를 2개를 사용하여 조회 성능 데이터를 각각 2개의 db가 처리하도록 한다?
Keyset + OFFSET 혼합 방식
(일반적인 페이지 이동은 Keyset Pagination을 사용하고,
사용자가 특정 페이지를 직접 입력하거나 점프하는 경우에만
제한적으로 OFFSET 기반 조회를 사용하는 혼합 방식)RDS 스펙 업그레이드
또한 에펨코리아(https://www.fmkorea.com/)와 같은 대형 커뮤니티는 제가 원하는 페이지 네이션 방식을 사용하면서 깊은페이지(최대 1만)도 지원하고
동시접속자 수십만
페이지 수천~수만
대량 데이터
환경에서도 빠른 조회 성능을 유지하는데
👉이러한 서비스들은 어떤 방식으로 pagination 및 조회 성능을 처리하는지 궁금합니다.
回答 1
0
안녕하세요, 인프런 AI 인턴입니다. 문영훈님.
인덱스 사용과 관련하여 복잡한 쿼리에서 성능 최적화에 대한 질문을 주셨네요. 현업에서 인덱스 최적화는 DB 성능을 극대화하는 중요한 작업 중 하나입니다. 주신 리스트와 같은 조건이 인덱스 효율성을 낮출 수 있고, 이를 고려하여 쿼리를 작성하는 것이 일반적입니다.
쿼리 최적화 방법:
OR 조건의 활용:
- 말씀하신 것처럼
OR조건은 인덱스 효율성을 저하시킬 수 있습니다. 따라서, 가능하다면 쿼리를 재구성하여UNION ALL또는 다른 구조로 변경해 성능을 개선할 수 있습니다.
- 말씀하신 것처럼
햄스터와 조합해 보기:
- 데이터베이스 옵티마이저가
OR조건을 잘 처리하지 못할 경우UNION ALL을 사용함으로써 개별 조건의 인덱스를 탈 수 있도록 해주는 것이 좋습니다.
- 데이터베이스 옵티마이저가
함수와 연산자의 사용:
- 인덱스가 적용되는 필드에 함수를 적용하면, 인덱스를 활용하지 못할 수 있습니다. 함수를 사용하지 않고 필드를 직접 비교하도록 쿼리를 수정하는 것이 좋습니다.
- 인덱스가 적용되는 필드에 함수를 적용하면, 인덱스를 활용하지 못할 수 있습니다. 함수를 사용하지 않고 필드를 직접 비교하도록 쿼리를 수정하는 것이 좋습니다.
LIKE와 와일드카드 사용:
LIKE문법에서는 가장 앞에%를 붙이지 않는 것이 좋습니다.%를 앞에 붙일 경우, 인덱스가 무용지물이 되기 쉽습니다.
널 비교:
NULL값의 비교나IS NOT NULL조건을 자주 사용하는 경우에도 주의가 필요합니다. 옵티마이저가 인덱스를 사용하지 않을 가능성이 높습니다.
샘플 데이터 추출을 통한 성능 테스트:
- 인덱스 설계를 변경하거나 쿼리를 재구성해 볼 수 있습니다.
- 인덱스 설계를 변경하거나 쿼리를 재구성해 볼 수 있습니다.
이러한 조건을 모두 고려하면서 쿼리를 작성하는 것이 이상적이지만, 실제로는 데이터 구조와 쿼리 사용 내역을 기반으로 필요한 부분만 중점적으로 최적화합니다.
문영훈님께서 언급하신 문제에 대해 더 많은 예시나 이해를 돕고자 비슷한 문제를 다룬 게시글을 추천드립니다:
- 효율적인 인덱스 사용과 쿼리 최적화 전략
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해 드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
Build 관련 문제 (테스트 관련 문제)
0
36
1
비관적 락 구현 방식 문의 건
0
63
2
외부 api 처리 방안에 대하여 궁금한 점이 있습니다.
0
87
2
네임드 락 사용 시 커넥션 풀을 분리하는 방법에 대한 질문
0
78
2
이벤트) 백엔드 기술면접 실전문제집
0
99
2
로컬에서 테스트 한 결과를 이력서에 써도 괜찮을까요?
0
128
2
데드락 발생 시, 외래 키를 제거하는 방법 관련 질문
0
83
2
Redis 캐싱을 도입하는데 db조회와 성능이 차이가 거의 없습니다.
0
107
2
k6 부하테스트 중인데 개선 전 성능이 너무 안나와서 고민
0
117
2
강의와 성능수치 비교
0
101
2
13강 강의 뒷부분의 과제 안내부분은 어디있나요?
0
49
2
이벤트 참가자 수 증가 후, save 메서드 호출 코드 질문
0
64
2
[수업 자료 질문] Cache Aside의 특징 문의
0
82
2
[수업자료 문의] RedisTemplate으로 SETNX 시 리턴값 문의
0
79
2
블로그에 학습 내용 정리 포스트를 올려도괜찮나요?
0
107
2
멀티스레드 상황인데 currentParticipants 가 AtomicInteger가 아닌 이유?
0
86
3
클라우드 환경 배포시 부하 테스트 방식에 대하여
0
136
2
k6 dashboad 안나오는 상
0
111
2
2-4 도커 빌드 에러가 계속 납니다.
0
295
2
AWS EC2에 도커 컨테이너가 동작하지 않을 때 확인 해야하는 것
0
113
2
성능 측정시
0
106
2
API 별 실행 쿼리 모니터링 구현 질문 있습니다.
0
80
2
이력서 작성에 대한 질문
0
105
2
트랜잭션 격리성 설계도 어필포인트로 가져갈 수 있을까요?
1
63
2

