본문으로 건너뛰기
SQLD 준비실
이론 전체 목차 열기 28 / 32

SQL 고급활용 및 튜닝 · 고급 튜닝 28 / 32

고급 SQL 튜닝

조건절 작성, 서브쿼리 변환, 불필요한 정렬 제거, 부분 범위 처리 같은 고급 튜닝 사고방식을 정리합니다.

출제 빈도 ★★★☆☆ 관련 문제 3개 | 서브쿼리 변환부분범위불필요한 정렬 제거

고급 튜닝은 SQL 모양을 바꾸는 일

인덱스를 추가하지 않아도 SQL 작성 방식만 바꿔 성능이 좋아질 수 있습니다. 고급 튜닝은 옵티마이저가 더 좋은 계획을 선택할 수 있도록 SQL을 명확하고 효율적인 형태로 고치는 작업입니다.

조건절을 인덱스 친화적으로 작성하기

컬럼을 함수로 감싸면 일반 인덱스를 사용하기 어려울 수 있습니다.

WHERE SUBSTR(phone, 1, 3) = '010'

가능하면 저장 구조와 조건을 함께 검토합니다. 날짜도 마찬가지입니다.

WHERE TO_CHAR(order_date, 'YYYY-MM-DD') = '2026-04-22'

대신 범위 조건을 사용하면 컬럼 원형을 유지할 수 있습니다.

WHERE order_date >= DATE '2026-04-22'
  AND order_date < DATE '2026-04-23'

불필요한 정렬 줄이기

ORDER BY, GROUP BY, DISTINCT, UNION은 정렬이나 해시 작업을 유발할 수 있습니다. 꼭 필요한지 확인해야 합니다.

SELECT DISTINCT customer_id
FROM orders;

이미 customer_id가 유일한 결과를 만드는 구조라면 DISTINCT는 불필요할 수 있습니다. UNION도 중복 제거가 필요 없다면 UNION ALL이 더 단순합니다.

서브쿼리와 조인 변환

서브쿼리와 조인은 같은 결과를 만들 수 있는 경우가 많습니다.

SELECT *
FROM customer c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
);

이 쿼리는 주문이 있는 고객을 찾습니다. 같은 목적을 조인으로 작성할 수도 있습니다. 어떤 방식이 빠른지는 데이터 양, 중복 여부, 인덱스, 옵티마이저 변환 가능성에 따라 달라집니다.

부분 범위 처리

사용자가 첫 화면에서 일부 결과만 보는 업무라면 전체 결과를 모두 만든 뒤 보여주는 것보다 필요한 만큼 먼저 가져오는 방식이 유리할 수 있습니다.

SELECT *
FROM orders
ORDER BY order_date DESC
FETCH FIRST 20 ROWS ONLY;

정렬 기준과 맞는 인덱스가 있으면 상위 일부만 빠르게 읽을 수 있습니다.

집계 튜닝

대량 집계는 많은 데이터를 읽습니다. 조건을 먼저 줄이고, 필요한 컬럼만 읽고, 적절한 그룹 기준을 사용하는 것이 중요합니다.

SELECT customer_id, SUM(amount)
FROM orders
WHERE order_date >= DATE '2026-01-01'
GROUP BY customer_id;

WHERE에서 기간을 먼저 줄이면 그룹화 대상도 줄어듭니다.

튜닝할 때 피해야 할 습관

  • 실행 계획을 보지 않고 인덱스부터 추가합니다.
  • SELECT *로 필요 없는 컬럼까지 읽습니다.
  • 중복 제거가 필요 없는데 DISTINCT를 붙입니다.
  • 조건 컬럼에 함수를 습관적으로 적용합니다.
  • 데이터 분포를 보지 않고 힌트를 고정합니다.

한 문장 요약

고급 튜닝은 같은 결과를 더 적게 읽고, 덜 정렬하고, 더 빨리 멈추도록 SQL을 바꾸는 일입니다.