본문 바로가기
Log/Trouble shoot

Postgres_인덱스 적용 후 성능이 개선되지 않는 문제

by RIEM 2023. 3. 13.
728x90

배경

대용량 트래픽 처리를 위한 node.js 기반 서버를 구축하는 프로젝트를 진행했습니다. 트래픽 처리가 가능한지 검증하기 위해 부하 테스트 툴인 nGrinder을 사용했습니다. 프로젝트를 진행하던 중 발생한 성능 문제를 인덱스로 해결하는 과정에 대한 글입니다.

인덱스를 사용하게 된 계기

신발 사이즈를 기반으로 고객의 입찰 데이터들을 검색하는 상세 조회(findById) API를 테스트하는 도중 응답속도와 처리량이 급격히 감소하는 현상이 발생했습니다. 이 쿼리는 특정 신발 사이즈(bidSize) 조건과 함께 입찰 생성 날짜(createdAt) 내림차순으로 필터링하고 있던 상황이었습니다. 이에 검색 성능을 개선하고자 신발 사이즈(bidSize)에 인덱스를 적용했으나 성능은 개선되지 않았습니다.

문제 원인

문제의 원인은 데이터의 분포에 있었습니다. 아무리 데이터가 많더라도 신발 사이즈는 250 - 300 범위 내로 귀결됩니다. 즉, 데이터들간 중복도가 높기 때문에 인덱스의 효과가 감소하는 것이 문제의 원인이었습니다.

해결

이를 해결하기 위해 중복도가 낮은 컬럼인 생성 날짜(createAt)에 인덱스를 적용했고, 기존 응답 속도는 490ms에서 99.5ms로 감소하여 검색 성능을 약 75% 이상 개선할 수 있었습니다.

인덱스 적용 전

 

인덱스 적용 후

 

개선 전 쿼리 실행 계획
개선 후 쿼리 실행 계획

정리

인덱스로 성능을 개선하는 과정에서 기억하고 싶은 핵심 키워드 3가지를 정리해보았습니다.

  1. Postgres 스캔 방식
  2. cardinality(카디널리티)
  3. IO 비용

블로그를 참조하다보면 인덱스는 일단 기본적으로 써야 한다는 맥락의 글을 자주 봤습니다. 하지만 이 실험을 통해 인덱스는 Postgres 엔진이 데이터를 효과적으로 스캔하기 위한 여러 방법 중 하나이고, 또 컬럼의 성격과 스캔 할 데이터의 크기에 따라서 인덱스의 효과는 미미할 수 있다는 점이다.

만약 인덱스를 생성한다면 데이터의 중복도를 나타내는 지표인 cardinality를 고려하는 것이 인덱싱 대상을 결정하는데 도움이 된다. 그리고 마지막으로 이러한 결정들이 모여 시스템 전체의 성능에 영향을 미친다는 점을 경험했다.

관련 실험

https://meir.tistory.com/430

728x90

댓글