소트와 페이징 튜닝
ORDER BY, DISTINCT, GROUP BY, UNION이 만드는 정렬 비용과 Top N·페이징 쿼리 튜닝 기준을 정리합니다.
출제 빈도 ★★★☆☆ 관련 문제 3개 |
ORDER BYDISTINCTTop N 정렬은 생각보다 비싸다
ORDER BY는 결과를 보기 좋게 만드는 기능이지만, 데이터가 많으면 큰 비용이 듭니다. DISTINCT, GROUP BY, UNION도 중복 제거와 그룹화를 위해 정렬이나 해시 작업을 유발할 수 있습니다.
정렬 대상이 메모리에 다 들어가지 않으면 임시 공간을 사용하게 되고, 이때 성능이 크게 떨어질 수 있습니다.
정렬을 만드는 대표 문법
| 문법 | 정렬 또는 중복 처리 가능성 |
|---|---|
ORDER BY | 최종 결과 순서 정렬 |
GROUP BY | 그룹화를 위한 정렬 또는 해시 |
DISTINCT | 중복 제거 |
UNION | 합친 뒤 중복 제거 |
윈도우 함수 ORDER BY | 파티션 내부 순서 계산 |
중복 제거가 필요 없다면 UNION보다 UNION ALL이 단순합니다.
Top N 튜닝
Top N은 전체를 다 정렬한 뒤 일부만 버리는 방식이면 비효율적입니다. 정렬 기준과 맞는 인덱스가 있으면 앞부분만 읽고 멈출 수 있습니다.
SELECT order_id, order_date, amount
FROM orders
ORDER BY order_date DESC
FETCH FIRST 20 ROWS ONLY;
order_date DESC 순서의 인덱스가 적절하다면 최신 주문 20건을 빠르게 찾을 수 있습니다.
페이징 쿼리 주의점
페이지 번호가 뒤로 갈수록 OFFSET 방식은 앞의 많은 행을 건너뛰어야 합니다.
SELECT order_id, order_date
FROM orders
ORDER BY order_date DESC
OFFSET 10000 ROWS FETCH NEXT 20 ROWS ONLY;
이런 쿼리는 10020건을 읽고 앞 10000건을 버리는 식으로 동작할 수 있습니다. 대량 페이지 이동이 잦다면 마지막으로 본 키를 기준으로 다음 페이지를 조회하는 방식도 고려합니다.
SELECT order_id, order_date
FROM orders
WHERE order_date < :last_order_date
ORDER BY order_date DESC
FETCH FIRST 20 ROWS ONLY;
정렬 비용 줄이는 기준
- 꼭 필요한 정렬인지 확인합니다.
- 중복 제거가 필요 없으면
UNION ALL을 사용합니다. - 정렬 기준과 조회 조건에 맞는 인덱스를 검토합니다.
- 화면에서 일부만 필요하면 Top N 방식으로 빨리 멈추게 합니다.
- 뒤쪽 페이지가 많은 업무는 단순
OFFSET의 비용을 확인합니다.
한 문장 요약
소트 튜닝은 전체를 다 정렬하지 않고, 필요한 순서의 필요한 범위만 읽게 만드는 일입니다.