PostgreSQL에서 LIMIT/OFFSET 쓸 때 주의할 점

여러분이 간단한 게시판을 하나 만들었다고 생각해보자.

SELECT * FROM articles;

를 하면 모든 게시글을 다 가져올 수 있을것이다.

게시글이 많아져서, 게시판에 Pagination을 적용하려고 한다.

한 페이지에 30개정도씩 보여주면 될 것이다.

5페이지 게시글을 보여주려면

SELECT * FROM articles LIMIT 30 OFFSET 120;

을 하면 될 것 같다.

음… 예상하지 못했던 게시글들이 보인다.

뭐가 문제지..?


정답은 ORDER BY 절이 빠졌기 때문이다.

ORDER BY 절은 ORDER BY 이후에 표시된 컬럼들을 기준으로 순서대로 정렬해준다.

ORDER BY 절이 없다면, 쿼리는 일정한 순서 보장 없이, 아무렇게나 순서를 정해 결과를 전해주게 된다.

즉, 위에 예시에서 보면 articles 테이블의 데이터를 아무렇게나 줄세운 후, 앞에 120개는 버리고 최대 30개의 글만 리턴하게 된다.

맞다. 아무렇게나 30개 뽑아주는거랑 같은 것 이다.

그래서 실제로 저렇게 실행하게 되면, 아무런 순서없이 최대 30개를 반환하게 된다.

그러면 이거 버그아닌가? 라고 생각할 수 있다.

하지만 PostgreSQL에 의하면, 그저 SQL의 본질적인 특성인 ORDER BY 없으면 실행결과의 순서는 보장하지 않는다 의 결과라, 버그가 아니다 라는 입장이다.

따라서 LIMITOFFSET 을 사용한다면, 사용자가 꼭 ORDER BY 를 빼먹지 않도록 체크하자.