티스토리 뷰

현업에서 데이터가 폭증함에 따라 시스템 성능 저하를 경험하게 되는 경우가 많습니다. 특히, 페이지네이션과 같이 자주 사용되는 기능에서 성능 문제가 발생하면 사용자 경험에 직접적인 영향을 미치기 때문에, 이를 최적화하는 일은 개발자에게 중요한 도전 과제가 됩니다.

 

주니어 개발자가 운이 좋다면 관련 경험이 풍부한 시니어 개발자의 도움을 받아 문제를 해결할 수도 있지만, 현실적으로는 대부분 스스로 해결책을 찾아야 하는 경우가 많습니다. 처음엔 막막하고 어디서부터 시작해야 할지 모를 수 있지만, 작은 문제들을 하나씩 해결하며 기술적으로 성장하는 계기가 되기도 합니다.

 

저 또한 이런 상황을 여러 번 겪었고, 이번에는 300만 건 이상의 데이터를 처리하는 페이지네이션 성능을 최적화해야 하는 상황에 직면했습니다. 부족한 지식으로 시행착오를 겪으며 배운 것들을 정리해 보니, 비슷한 문제를 겪고 있을 다른 개발자들에게 도움이 될 것 같아 공유하고자 합니다. 이번 글에서는 제가 겪었던 문제 상황과 이를 해결하기 위해 적용한 기술, 그리고 개선된 결과를 상세히 설명하겠습니다.

 

문제 상황

개인정보 사용이력을 관리하는 이력 조회 페이지에서 페이지네이션을 적용해서 결과를 반환해야 했습니다. 그러나 데이터가 자연스럽게 100만 건 이상 쌓이면서 조회 성능을 개선해야하는 상황이 됐습니다.

 

1. 느린 조회 속도:

  • OFFSET 기반 페이지네이션(LIMIT 10 OFFSET n)으로 페이지를 이동할수록 조회 속도가 급격히 느려짐.
  • 예를 들어, OFFSET이 100,000 이상인 경우 쿼리 실행 시간이 수 초를 넘음.

2. DB 부하 증가:

  • 매 페이지 요청마다 불필요한 데이터 스캔이 발생.

원인 분석

1. OFFSET의 동작 방식:

  • OFFSET은 데이터베이스가 요청된 만큼의 데이터를 모두 스캔한 후, 앞부분을 버리고 결과를 반환하는 방식.
  • 예를 들어, LIMIT 10 OFFSET 100000은 처음 100,000개의 행을 버리고 그다음 10개의 행을 반환하기 때문에 불필요한 작업이 많음.

2. 인덱스의 부재 또는 비효율적 사용:

  • 인덱스가 잘못 설계되어 성능이 저하됨.
  • 주요 조회 조건에 따른 복합 인덱스의 적용이 필요함.

해결 방안

1. OFFSET 제거 및 Keyset Pagination 도입

 

OFFSET 방식의 한계를 극복하기 위해 Keyset Pagination을 도입했습니다. Keyset Pagination은 마지막으로 조회된 항목의 키(예: id 또는 created_at)를 기준으로 다음 페이지 데이터를 가져오는 방식입니다.

구현 방법

기존  OFFSET 방식

SELECT * 
FROM history_log 
WHERE user_id = '12345'
ORDER BY created_at
LIMIT 10 OFFSET 1000;

 

개선된 Keyset Pagination 방식

SELECT * 
FROM history_log 
WHERE user_id = '12345'
  AND created_at > '2025-01-01 00:00:00'
ORDER BY created_at
LIMIT 10;

 

예제 사례들은 사내 보안을 고려해서 실제 테이블명과 컬럼명과 다르게 작성하고 있습니다 ㅎㅎㅎ

예제에는 생성일자로 정렬 후에 처리를 했지만 저는 ID값을 시퀀스로 사용해서 ID를 key로 Keyset Pagination 적용했습니다.

 

2. 복합 인덱스 생성

 

복합 인덱스의 경우는 카디널리티나 여러 조건들을 고려해서 설계해야하므로 나중에 추가적으로 글을 작성하겠습니다.

2025.01.13 - [개발 지식/데이터베이스] - 데이터베이스 성능의 핵심 | 인덱스와 복합 인덱스란 무엇인가?

 

결과

성능 개선 작업 이후, 다음과 같은 성과를 얻을 수 있었습니다. 적절한 인덱스 설계와 효율적인 페이지네이션 방식이 필요하다는 교훈을 얻었습니다. OFFSET의 한계를 이해하고, Keyset Pagination 같은 대안이 있다는 점을 배웠습니다.

  1. 쿼리 실행 속도 개선:
    OFFSET 방식에서 3초 이상 걸리던 요청이 Keyset Pagination으로 200ms 이하로 단축.
    페이지 깊이에 상관없이 응답 속도를 균일하게 유지.
  2. 사용자 경험 향상:
    페이지 이동 시 대기 시간이 줄어들어 더욱 원활한 경험 제공.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
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
글 보관함