결과 행을 제한하기

Hyun-jin Won·2021년 10월 5일
0

MySQL로 SQL 시작하기

목록 보기
9/24
post-thumbnail

결과를 제한하는 방식

SELECT 명령에서 일부 데이터 반환을 제한할 수 있다.
이를 지원하는 기능이 바로 LIMIT 이다.

SELECT COLUMNS FROM TABLE WHERE 조건 ORDER BY 정렬조건 LIMIT n;

위와 같이 SELECT 문장의 맨 뒤에 위치하게 되며 n에 최대출력할 행의 수를 입력한다.
최대의 수를 입력한다는 뜻는 즉 아무리 많이 나와도 n개를 초과하게 나오지 않는다는 의미이다.

또한 LIMIT의 역할을 통해 눈치챌 수도 있지만, LIMIT를 사용하게 되면 상당히 SQL의 속도를 빠르게 향상 시킬 수 있다. 하지만 이는 INDEX, 데이터의 상황, LIMIT의 크기, ORDER BY, GROUP BY 등의 상황에 따라 크게 다르다.
Does using LIMIT improve the performance and is it noticeable? - Stack Exchange

정렬과 조건이 중요한 이유

우리는 이전 정렬 파트에서 SELECT에 특정한 정렬값을 주지 않거나 정렬 조건이 구체적이지 않으면, 무작위로 데이터 순서가 나온다는 것을 알게 되었다. 여기서 LIMIT을 쓰게 될 경우 데이터를 잘못 읽게 되는 경우가 발생할 수 있다.

만약 내가 데이터 중 가장 최근에 생성되었고, 그 중 ID의 값이 작은 데이터부터 뽑아내고 싶을 때 단순히 ORDER BY 에 생성날짜만을 집어넣게 될 경우, ID의 순서에 상관없이 데이터가 랜덤으로 들어오기 때문에, LIMIT의 값이 검색한 데이터의 수 보다 크다면, 연속해서 SQL를 호출했을 때 항상 똑같은 값이 들어올 것이라는 보장이 없다.

이렇기 때문에 LIMIT 같은 결과 데이터의 수를 제한하는 명령어를 사용할 때에는 ORDER BY 나 WHERE 같은 데이터 순서나 조건에 상당히 신경을 써야한다.

오프셋 지정

웹에서 게시글목록 출력을 위해 게시글을 조회한다면, 전체 데이터를 조회해서 넘겨줘야 할까?

여러 사이트의 게시판을 보면 일반적으로 일정 갯수의 게시글이 노출되고, 페이지를 선택하여 다음 게시글 목록을 볼 수 있다. 그렇다면 이렇게 적게는 수십, 많게는 수십만개의 게시글을 DB에서 조회한다면 웹에서는 얼마나 데이터를 가져올까?

조금만 생각해본다면 유저가 사실상 게시글을 끝페이지 까지 갈 일은 별로 없으며, 데이터 전체를 넘겨준다면 시간적으로, 비용적으로 상당한 낭비라는 것을 깨닫게 될 것이고, 그렇다면 우리가 앞서 배운 LIMIT을 통해서 이를 제한해서 보낼 수 있을 것이다.

하지만 다음 페이지의 데이터를 어떻게 알고 해당 사이의 데이터만 가져오게 할 수 있을까? MySQL은 이 해답을 위해 OFFSET을 제공한다.

SELECT COLUMNS FROM TABLE WHERE 조건 ORDER BY 정렬조건 LIMIT n OFFSET m;

OFFSET은 일종의 페이지 역할을 하게 된다.
OFFSET의 값이 주어지면 DBMS은 데이터를 LIMIT만큼 가져오되, 행의 m * n 의 위치부터 데이터를 가져오게 된다. 이를 통해서 데이터의 갯수를 제한하되, 특정 사이의 값을 가져올 수 있게 된다.

profile
삽질을 주체하지 못하는 잉간

0개의 댓글