사용자 도구

사이트 도구


database:seek_method

seek method

offset/limit 기반 페이징의 문제점

  • offset/limit 기반의 페이징 조회는 offset이 뒤로 갈 때마다(즉, 페이지 번호가 커질 때마다) 성능이 계단현상으로 안 좋아지게 된다.
  • 또한, 페이지를 이동하는 사이에 where조건에 속하는 데이터가 이미 조회를 마친 페이지 부분에서 추가/삭제가 발생하면
    • 데이터 추가시 : 그 뒷 페이지에서 앞선 조회에서 나왔던 데이터가 새로 추가된 데이터로 인해 뒤로 밀리면서 뒷편 페이징에서 다시 출현하게됨.
    • 데이터 삭제시 : 이번 페이지에서 맨 앞부분에 조회되었어야할 데이터가 앞 선 페이지에서의 데이터 삭제로 바로 앞 페이지 쪽으로 이동하면서 조회가 안되고 누락되는 현상 발생.
  • 거기에다 totalCount까지 매번 세개 되면 성능저하가 더 커지게 된다.

seek method

  • 이를 해결하려면 PK id 값으로 정렬을 하고(보통은 asc, DB 자체 기본 PK 정렬을 사용)
  • 처음에는 PK값 제약없이 조회, 조회 결과 limit 이 10이면 마지막 PK값 기억
  • 그 다음부터는 asc 일 때 PK > [앞선 조회의 마지막 PK] limit [pageSize] 형태로 조회를 이어나간다.
    • 물론 desc 일 때< 로 한다.
  • 이 방식을 seek method라고 부르는 듯 하며 (명확한 용어 정의가 된 상태는 아님) 더 보기(more) 방식이라고 하기도 한다.
  • 조회 일관성을 위해 일정한 order by PK asc|desc는 항상 있어야 한다. 이는 모든 페이징 기법에서 마찬가지 이다.

주의

  • 최초 시작 쿼리의 경우에도 PK >= 미리따로구한_min(PK column) 를 넣어주는게 좋다. 이걸 하지 않으면 전체 정렬이 발생할 수 있다. 두번째 쿼리 부터는 PK의 최소값 비교가 항상 들어가므로 상관없다.
  • 모든 seek method 쿼리에는 PK ⇐ 미리따로구한_max(PK column) 값을 항상 조회 조건에 넣어주는게 좋다(desc는 반대).
  • 이렇게 해야 불필요한 전체 정렬(PK >= min의 역할)이나, 잘못된 인덱스를 타는 현상(PK <= max 의 역할)이 발생하지 않는다.

최종 형태

  • asc 정렬일 때 기준이며, desc이면 반대로 해야한다.
SELECT MIN(PK) FROM TABLE; -- 값 저장: pkmin
SELECT MAX(PK) FROM TABLE; -- 값 저장 : pkmax
-- 조회 시작시
SELECT *
FROM TABLE
WHERE 
  pk >= [pkmin]
  AND pk <= [pkmax]
  [기타조건]
  ORDER BY pk ASC
  LIMIT [pageSize]
 
-- 그 뒤부터는
SELECT *
FROM TABLE
WHERE 
  pk > [앞선 조회의 마지막 PK값]
  AND pk <= [pkmax]
  [기타조건]
  ORDER BY pk ASC
  LIMIT [pageSize]

참조

database/seek_method.txt · 마지막으로 수정됨: 2023/05/31 13:27 저자 kwon37xi