홈 › SQL 실무 › 01 / 9

페이징 쿼리

ROWNUM, LIMIT, OFFSET FETCH, 키셋 페이징
섹션 6진행 0 / 9

5. 자주 하는 실수 (Tip)

실수 1: 정렬에 유일한 컬럼이 없다

ORDER BY created_at DESC 만 쓰면 예제 1 의 동점 행들이 페이지 경계에서 겹치거나 빠질 수 있습니다. 우연히 같은 순서로 나와서 개발 중에는 안 보이다가 데이터가 늘거나 인덱스가 바뀌면 나타납니다. id 를 마지막에 덧붙입니다.

실수 2: ROWNUM 을 정렬 전에 자른다

SELECT ... FROM board WHERE ROWNUM <= 10 ORDER BY created_at DESC 는 임의의 10 행을 가져와서 그 10 행을 정렬합니다. 상위 10 건이 아닙니다. 정렬은 인라인 뷰 안에서 끝내고 바깥에서 ROWNUM 을 씁니다.

실수 3: 뒤 페이지가 점점 느린데 인덱스만 늘린다

OFFSET 100000 이 느리면 인덱스를 더 만들어도 한계가 있습니다. 앞 10만 행을 세어야 하기 때문입니다. 뒤로 깊이 들어가는 목록(무한 스크롤, 배치 순회)은 키셋 방식으로 바꿉니다. 키셋은 (created_at, id) 복합 인덱스가 정렬 순서와 같아야 빠릅니다.

실수 4: 키셋에서 행 값 비교를 그대로 옮긴다

WHERE (created_at, id) < (:c, :i) 는 MySQL 에서만 됩니다. MSSQL 은 지원하지 않고 Oracle 은 이 형태의 대소 비교를 쓰지 않습니다. OR 로 풀어 쓴 형태를 씁니다. 또 정렬 방향이 섞이면(날짜 내림차순, id 오름차순) 부등호도 컬럼마다 맞춰야 하고, 행 값 비교는 그런 경우에 쓸 수 없습니다.