사용자 도구

사이트 도구


database:seek_method

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

다음 판
이전 판
database:seek_method [2022/03/22 16:57]
kwon37xi 만듦
database:seek_method [2023/05/31 13:27] (현재)
kwon37xi [seek method]
줄 1: 줄 1:
 ====== seek method ====== ====== seek method ======
 +  * 명칭이 명확하지 않음.
 +  * seek method, keyset pagination 등으로 불리는 듯.
 +  * [[java:jpa:springdatajpa|Spring Data JPA]] 3.1에 관련 기능이 추가됨.
 +    * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.scrolling.keyset
  
 +
 +===== 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''이면 반대로 해야한다.
 +<code sql>
 +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]
 +</code>
 ===== 참조 ===== ===== 참조 =====
   * [[https://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/|Why Order By With Limit and Offset is Slow - Faster Pagination in Mysql]]   * [[https://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/|Why Order By With Limit and Offset is Slow - Faster Pagination in Mysql]]
   * [[https://use-the-index-luke.com/sql/partial-results/fetch-next-page|OFFSET is bad for skipping previous rows]]   * [[https://use-the-index-luke.com/sql/partial-results/fetch-next-page|OFFSET is bad for skipping previous rows]]
 +  * [[https://use-the-index-luke.com/no-offset|We need tool support for keyset pagination]]
   * [[https://blog.jooq.org/faster-sql-paging-with-jooq-using-the-seek-method/|Faster SQL Pagination with jOOQ Using the Seek Method – Java, SQL and jOOQ.]]   * [[https://blog.jooq.org/faster-sql-paging-with-jooq-using-the-seek-method/|Faster SQL Pagination with jOOQ Using the Seek Method – Java, SQL and jOOQ.]]
-  * +  * [[https://techblog.woowahan.com/2662/|Spring Batch와 Querydsl]] : ''min(PK),max(PK)''를 비교 조건에 넣어야 하는 이유. 
 +  * [[https://vladmihalcea.com/sql-seek-keyset-pagination/|SQL Seek Method or Keyset Pagination - Vlad Mihalcea]]
  
database/seek_method.1647935844.txt.gz · 마지막으로 수정됨: 2022/03/22 16:57 저자 kwon37xi