쿼리 성능 향상을 위해 필수적인 기법인 Row Limiting은 SQL 쿼리에서 특정 개수의 행(Row)만 조회하도록 제한하는 기법을 의미합니다. 주로 부분범위처리를 할때 사용합니다.

예전엔 where절에 rownum 조건으로 제한하곤 했는데, 오라클 12C 이상 버전부터 새로운 기능이 추가되어 기본적인 사항부터 차근차근 한번 알아보고자 합니다.

  1. 페이징 처리(Pagination)
    → 웹 애플리케이션에서 한 번에 전체 데이터를 조회하는 대신, 일정 개수만 가져와서 페이지별로 나누어 보여주는 기능
  2. TOP N 쿼리(상위 N개 결과 조회)
    → 가장 높은 점수의 학생 10명 조회, 최신 등록된 상품 5개 조회 등의 시나리오
  3. 데이터 샘플링
    → 큰 데이터셋에서 랜덤하게 일부 데이터만 가져와서 테스트하거나 분석하는 경우

Oracle에서 Row Limiting(행 제한)을 설정하는 방법은 Oracle 버전에 따라 다르게 적용됩니다. 최신 버전(Oracle 12c 이상)에서는 표준 SQL 방식인 OFFSETFETCH를 사용할 수 있으며, 이전 버전에서는 ROWNUM 또는 ROW_NUMBER()를 활용해야 합니다.

1. Oracle 12c 이상: OFFSET … FETCH 사용 (추천)

Oracle 12c부터 도입된 OFFSETFETCH 절을 사용하면 페이징 처리행 제한을 쉽게 구현할 수 있습니다.

✅ 첫 N개 행만 가져오기 (FETCH FIRST n ROWS ONLY)

SELECT *
FROM employees
ORDER BY employee_id
FETCH FIRST 10 ROWS ONLY;

✅ 위 쿼리는 employee_id 기준으로 정렬된 데이터 중 상위 10개 행을 반환합니다.

오라클 12c부터 /*+ first_rows(n) */ 힌트를 사용하면 힌트에 지정한 n으로 카디널리티를 계산하므로 비교적 인덱스를 잘 사용합니다. 페이징 처리에 윈도우 함수 또는 Row Limiting 기능을 사용한다면 /*+ first_rows(n) */ 힌트를 같이 사용해주는 것이 좋습니다.

✅ 특정 위치부터 N개 행만 가져오기 (OFFSET n ROWS FETCH NEXT n ROWS ONLY)

SELECT *
FROM employees
ORDER BY employee_id
OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY;

✅ 위 쿼리는 처음 5개 행을 건너뛰고, 그 다음 10개 행을 가져옵니다.

주의사항!!!

2. Oracle 12c 이전 버전: ROWNUM 사용

ROWNUM은 Oracle에서 제공하는 가상 열로, 실행되는 순서대로 번호를 부여합니다. 하지만 ORDER BY보다 먼저 적용되므로, 정렬된 데이터를 정확하게 제한하려면 서브쿼리를 사용해야 합니다.

✅ 정렬된 결과의 상위 N개 행 가져오기

SELECT *
FROM (
SELECT *
FROM employees
ORDER BY employee_id
)
WHERE ROWNUM <= 10;

ROWNUMORDER BY보다 먼저 평가되므로, 반드시 서브쿼리를 사용하여 정렬 후 제한을 적용해야 합니다.

3. Oracle 12c 이전 버전: ROW_NUMBER() 사용 (권장)

ROWNUM을 사용할 경우 ORDER BY를 적용하기 어렵기 때문에, ROW_NUMBER() 함수를 활용하면 보다 유연한 행 제한이 가능합니다.

✅ 특정 위치부터 N개 행만 가져오기

SELECT *
FROM (
SELECT employees.*, ROW_NUMBER() OVER (ORDER BY employee_id) AS rn
FROM employees
)
WHERE rn BETWEEN 6 AND 15;

ROW_NUMBER()를 사용하면 ORDER BY가 제대로 적용되며, 특정 범위의 행을 가져올 수 있습니다.

4. ROWNUM vs ROW_NUMBER() 차이점

방법설명장점단점
FETCH FIRST최신 SQL 표준 방식간결하고 빠름Oracle 12c 이상에서만 사용 가능
ROWNUM빠르고 간단함Oracle 11g 이하에서 사용 가능ORDER BY 적용이 어렵고 서브쿼리가 필요함
ROW_NUMBER()ORDER BY와 함께 유연한 행 제한 가능페이징 처리에 적합성능이 상대적으로 느릴 수 있음

결론

  • Oracle 12c 이상: FETCH FIRST ... OFFSET 방식 사용 (권장 ✅)
  • Oracle 11g 이하: ROW_NUMBER() 또는 ROWNUM 사용
    • 단순한 경우 → ROWNUM
    • 정렬이 필요하거나 페이징 처리 → ROW_NUMBER()

이제 버전에 따라 가장 적절한 방법을 사용하여 행 제한을 적용하면 됩니다! 🚀

zerg96

Recent Posts

요양원 선택 전 반드시 확인해야 할 것들, 부모님 맡기기 전에 보세요

요양원 선택 전 반드시 확인해야 할 체크리스트를 공개합니다. 공식 평가 자료 조회법, 방문 시 확인…

2일 ago

공공기관 채용 비리, 내부에서 터져나온 충격 증언

공공기관 채용 비리의 실태와 피해 지원자의 대응법을 정리했습니다. 채용 비리 신고 방법, 공익신고자 보호제도, 취준생…

2일 ago

주식 손실 났을 때 세금 줄이는 방법, 아는 사람만 씁니다

주식 손실을 세금 절약에 활용하는 합법적 방법을 공개합니다. 해외주식 손익통산, ISA 계좌 활용, 연금계좌 절세까지…

2일 ago

음식 배달 늦으면 소비자가 취소할 수 있다, 몰랐던 권리

배달이 예상 시간보다 크게 늦으면 취소·환불을 요청할 수 있습니다. 배달앱별 지연 취소 방법과 잘못 배달됐을…

2일 ago

휴대폰 요금제 바꾸면 연 수십만원 절약, 지금 내 요금제 확인하세요

통신비 절약의 핵심은 요금제 최적화입니다. 내 데이터 사용량 확인법, 알뜰폰 전환 비교, 위약금 없이 요금제…

2일 ago

퇴직금 못 받았다면, 지금 당장 이렇게 하세요

퇴직 후 퇴직금을 받지 못했다면 즉시 노동부에 신고하세요. 지급 기한, 자격 요건, 신고 방법, 소액체당금…

2일 ago