Post

03 Paging

03 Paging

1. Note

  • 페이징처리..!

2. Paging

1. Paging

  • 데이터를 한 번에 전부 가져오지 않고, 일정 단위(페이지)로 나눠서 가져오는 방식
  • 사용자는 필요한 데이터만 한 번에 조회할 수 있으며,
  • 전체 데이터를 나누어 제공함으로써 성능을 최적화가능함.

2. 주요목적

1. 성능최적화

  • 대량 데이터를 한 번에 조회하면 DB와 서버에 큰 부담이 생김
  • 조회 시간도 길어지고 메모리 사용량도 급격히 증가함
  • 페이징은 필요한 개수만 조회하도록 제한해서 이런 문제를 줄임
  • 결과적으로 시스템 전체의 안정성과 응답 속도를 유지할 수 있음

2. 사용자 경험 개선

  • 사용자는 많은 데이터를 한 번에 보는 것보다 나눠 보는 것이 편함
  • 페이징을 적용하면 화면이 깔끔해지고 원하는 정보를 찾기 쉬워짐
  • 또한 초기 로딩 속도가 빨라져 체감 성능이 좋아짐
  • 무한 스크롤이나 페이지 이동 같은 UI 구현도 가능해짐

3. 네트워크 비용 절약

  • 한 번에 많은 데이터를 전송하면 응답 크기가 커짐
  • 이는 특히 모바일 환경에서 속도 저하로 이어질 수 있음
  • 페이징을 사용하면 필요한 데이터만 전송하게 되어 효율적
  • 그 결과 트래픽 사용량과 응답 지연을 줄일 수 있음

3. 동작원리

1. LIMIT

  • 조회할 데이터의 최대 개수를 제한
  • 한 번에 몇 개의 데이터를 가져올지를 결정
  • SQL
    1
    2
    
    -- 최대 10개의 데이터만 조회
    SELECT * FROM user LIMIT 10;
    

2. OFFSET

  • 조회 시작 위치를 지정하며, 앞의 데이터를 건너뜀
  • 몇 번째 데이터부터 가져올지를 결정함
  • SQL
    1
    2
    
    -- 앞의 20개를 건너뛰고 이후부터 조회
    SELECT * FROM user OFFSET 20;
    

3. 혼합

1
2
// 21번째 데이터부터 10개 조회 (21 ~ 30번째)
SELECT * FROM user LIMIT 10 OFFSET 20;

3. 페이징 처리의 한계

1. OFFSET이 큰 경우 성능 저하 발생 이유

  • 문제 발생 원리
    • 데이터베이스는 OFFSET에 지정된 값만큼 데이터를 건너뛰기 위해
      • 결과 집합을 메모리에 로드하고,
      • 해당 범위의 데이터를 모두 스캔(Discard)
    • OFFSET의 값이 커질수록 건너뛰어야 하는 데이터가 많아져서 처리 시간이 급격히 증가함
  • 예시
    1
    2
    3
    4
    5
    6
    
    // 처음 100,000개의 데이터를 스캔하여 버린 후, 100,001번째 데이터부터 반환
    // 데이터베이스는 100,000개의 데이터를 읽고 정렬한 후 버리므로 CPU와 메모리를 낭비
    SELECT *
    FROM products
    ORDER BY id
    LIMIT 10 OFFSET 100000;
    

2. 데이터 양에 따른 성능 차이 분석

  • 소규모 데이터
    • OFFSET을 사용하는 페이징은 데이터 양이 적을 때 성능 문제가 거의 발생하지 않음.
    • 사용자가 페이지 이동을 하더라도 결과가 빠르게 반환.
  • 대규모 데이터
    • 데이터 양이 많아질수록 OFFSET 기반의 페이징은 점점 비효율적이 됨.
    • 10,000번째 페이지를 요청하면 데이터베이스는 999,990개의 데이터를 스캔 후 폐기해야 하므로 성능이 급격히 저하.

4. 페이징 최적화 전략

1. Keyset Pagination (커서 기반 페이징)

  • Keyset Pagination은 OFFSET을 사용하지 않고,
  • 이전 요청의 마지막 데이터 값을 기준으로 다음 데이터를 가져오는 방식
  • 작동 방식
    • 특정 정렬 기준(Key)을 사용하여 이전 요청의 마지막 데이터를 기준으로 이후 데이터를 가져옴
    • OFFSET이 필요하지 않아 불필요한 데이터 스캔을 방지.
  • 장단점
    • 장점
      • 대규모 데이터에서도 일정한 성능 유지.
      • 고정된 Key를 기반으로 필요한 데이터만 조회 가능.
    • 단점
      • 정렬 기준(Key) 설정이 복잡할 수 있으며, 페이지 번호 기반 탐색이 어려움.
  • SQL
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    -- 첫 번째 페이지 요청
    SELECT id, name, price, created_at
    FROM products
    ORDER BY id DESC 
    LIMIT 10; 
      
    -- 다음 페이지 요청
    SELECT id, name, price, created_at
    FROM products
    WHERE id < 마지막_id값 -- PK기반
    ORDER BY id DESC
    LIMIT 10;
    

2. 인덱스를 활용한 페이징 성능 개선

  • 정렬 및 검색 조건에 맞는 인덱스를 설계하여 페이징 성능을 최적화
  • 복합 인덱스를 활용하면 쿼리의 검색과 정렬 성능을 대폭 개선할 수 있음
  • SQL
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    -- 검색 조건 (WHERE)과 정렬 조건 (ORDER BY)을 인덱스가 모두 활용
    CREATE INDEX idx_category_created_at ON products(category_id, created_at);
      
    SELECT id, name, price, created_at
    FROM products
    WHERE category_id = 100 -- 인덱스 컬럼1
    ORDER BY created_at DES C -- 인덱스 컬럼2 (꼭 where이 아니여도 order에도 인덱스 걸림)
    OFFSET 0
    LIMIT 10; -- LIMIT은 한 번에 가져올 데이터의 수를 제한하며, OFFSET은 결과의 시작 지점을 지정
    

3. 필요한 데이터만 가져오는 최적화 기법

  • 조회 시 필요한 컬럼만 SELECT하여 네트워크와 메모리 사용량을 줄임
  • SQL 비교
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    -- 모든 컬럼을 조회하는 비효율적인 쿼리
    SELECT *
    FROM products
    WHERE category_id = 100
    ORDER BY created_at DESC
    OFFSET 0
    LIMIT 10;
      
    -- 필요한 컬럼만 조회하여 최적화
    SELECT id, name, price, created_at
    FROM products
    WHERE category_id = 100
    ORDER BY created_at DESC
    OFFSET 0
    LIMIT 10;
    
This post is licensed under CC BY 4.0 by the author.