Intro ⭐
일반적인 웹 사이트에서는 데이터를 조회할 때, 디스플레이의 한계 및 가독성 향상을 위해 데이터를 일정 개수만을 화면에 표현하곤 합니다.
MSSQL에서는 고맙게도 복잡한 로직 없이 페이징 기능을 간단히 개발할 수 있는 함수를 지원해 주고 있습니다.
ROW_NUMBER
ROW_NUMBER 함수를 사용하여 데이터의 순서를 지정하고, 특정 순서만을 WHERE 조건을 통해 조회하는 방식입니다. 조회 할때 마다 순서가 변경되지 않도록 OVER 절의 정렬(ORDER BY)는 필수입니다.
DECLARE @PAGE_NO INT = 1; -- 조회할 페이지 번호
DECLARE @PAGE_SIZE INT = 30; -- 한 페이지에 보여줄 행 수
SELECT
USERID, USERNAME, EMAIL
FROM (
SELECT
ROW_NUMBER() OVER(ORDER BY USERID) AS ROW_NO, USERID, USERNAME, EMAIL
FROM
TB_USER
) AS PAGING_DATA
WHERE
ROW_NO BETWEEN (@PAGE_SIZE * (@PAGE_NO - 1)) + 1 AND (@PAGE_SIZE * (@PAGE_NO - 1)) + @PAGE_SIZE
OFFSET & FETCH
MSSQL 11.x 버전 이후에만 지원하는 방식이며, ROW_NUMBER의 순서의 범위를 지정하는 것이 아닌 몇 행을 건너뛰고 몇 행을 보여줄 것인지를 지정합니다.
DECLARE @PAGE_NO INT = 1; -- 조회할 페이지 번호
DECLARE @PAGE_SIZE INT = 30; -- 한 페이지에 보여줄 행 수
SELECT
USERID, USERNAME, EMAIL
FROM
TB_USER
ORDER BY
USERID
OFFSET
@PAGE_SIZE * (@PAGE_NO - 1) ROW -- 건너 뛸 행 수
FETCH NEXT
@PAGE_SIZE ROW ONLY -- 보여줄 행 수
Honey Tip 🍯
데이터가 2,000만 건 이상 존재하는 테이블에서 두 방식 모두 시행해 본 결과 쿼리 비용의 차이는 없었습니다.
언뜻 보기에는 인라인 뷰(Inline View)를 이용한 ROW_NUMBER 방식이 성능이 떨어질 것으로 예상하였지만, 아직 주니어 개발자인 저는 MSSQL의 신 옵티마이저(Optimizer)의 방대한 계획을 이해하지 못하나 봅니다 😔
이미 상용화된 서비스라면 기존에 사용하던 방식을 이어가는 것이 좋겠지만, 개인적으로는 OFFSET & FETCH 구문이 가독성이 더 좋게 느껴집니다.
References
https://learn.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql?view=sql-server-ver16
ROW_NUMBER (Transact-SQL) - SQL Server
Transact-SQL reference for the ROW_NUMBER function. This function numbers the output of a result set.
learn.microsoft.com
해당 게시글은 독학을 통해 얻은 지식들을 취합하여 작성한 글입니다.
잘못된 내용이 있을 경우 댓글을 통해 지적을 해주신다면 저와, 이 글을 참조하게 될 모든 분들께 큰 힘이 됩니다.