본문 바로가기
카테고리 없음

서브쿼리와 뷰(View) 최적화

by 유형제맘 2025. 8. 11.

서브쿼리(Subquery)란?

서브쿼리는 다른 SQL문의 일부로 포함되어 실행되는 쿼리입니다. 주로 WHERE, FROM, SELECT 절에서 사용됩니다.
예시:

SELECT *
  FROM employees
 WHERE department_id = (
    SELECT department_id
      FROM departments
     WHERE department_name = 'Sales'
);

 

튜닝 관점: 서브쿼리의 위치와 작성 방식에 따라 실행 계획이 크게 달라집니다.

서브쿼리 유형별 성능 특성

1. 단일 행 서브쿼리

  • 반환값이 1개인 서브쿼리 (=, <, >, <= 비교)
  • 옵티마이저가 실행 순서를 단순화하기 쉽다

튜닝 포인트

  • PK나 Unique Index가 걸린 컬럼에서 단일 행 서브쿼리는 매우 빠름

2. 다중 행 서브쿼리

  • 여러 값을 반환 (IN, ANY, ALL 등)
  • IN → Hash Semi Join으로 변환 가능
  • NOT IN은 NULL 값 포함 시 성능 저하 가능

튜닝 포인트

  • NOT IN 대신 NOT EXISTS 권장
  • 반환 데이터가 많으면 조인으로 변환

3. 다중 컬럼 서브쿼리

  • 2개 이상의 컬럼 비교
  • 비교 대상이 인덱스 복합 컬럼과 일치하면 효율 ↑

4. 상관 서브쿼리(Correlated Subquery)

  • 외부 쿼리의 컬럼을 참조하는 서브쿼리
  • 외부 쿼리의 각 행마다 서브쿼리 실행 → 반복 실행 부담

튜닝 포인트

  • 가능하면 JOIN으로 변환하여 반복 실행 제거
  • 필터 조건을 외부 쿼리로 끌어올려 처리량 감소

IN vs EXISTS 성능 비교

-- IN 사용
SELECT * FROM employees e
WHERE e.department_id IN (
SELECT department_id FROM departments WHERE location_id = 1700
);

-- EXISTS 사용
SELECT * FROM employees e
WHERE EXISTS (
SELECT 1 FROM departments d
WHERE d.department_id = e.department_id
AND d.location_id = 1700
);
  • IN: 서브쿼리 결과를 메모리에 올려 검색 (데이터 양이 적을 때 유리)
  • EXISTS: 조건 만족 시 즉시 TRUE 반환 (데이터 양이 많을 때 유리)

서브쿼리 vs 조인 변환

  • 조인으로 변환하면 옵티마이저가 더 많은 실행 계획 최적화를 적용 가능
  • 특히 대용량 데이터 처리 시 효과적

예시:

-- 서브쿼리
SELECT e.*
  FROM employees e
 WHERE e.department_id IN (
    SELECT department_id
      FROM departments
     WHERE location_id = 1700
);

-- 조인 변환
SELECT e.*
  FROM employees e
    JOIN departments d
      ON e.department_id = d.department_id
 WHERE d.location_id = 1700;

 

옵티마이저가 내부적으로 Semi Join으로 변환 가능

뷰(View) 튜닝

1. 뷰의 장단점

  • 장점: 재사용성, SQL 단순화
  • 단점: 중첩 뷰(Nested View)는 성능 저하 가능
    (실행 계획이 깊어져 옵티마이저 최적화 어려움)


2. 인라인 뷰(Inline View)

  • FROM 절에 서브쿼리 작성
  • 임시 테이블처럼 사용
  • 정렬, 집계 결과를 조인 전에 축소 가능

튜닝 포인트

  • 인라인 뷰에서 불필요한 컬럼 제거 → I/O 감소
  • 정렬/집계를 먼저 수행해 데이터 양 축소

3. MERGE VIEW / INLINE VIEW 처리

  • MERGE VIEW: 뷰를 원본 쿼리에 합쳐 실행
    → 인덱스 활용 가능, 성능 향상
  • INLINE VIEW: 뷰를 인라인 형태로 변환해 조인
    → 복잡한 조인 쿼리에서 데이터 양 축소 효과

튜닝 사례

문제 상황 개선 방법 효과
상관 서브쿼리 반복 실행 조인 변환 CPU 사용량 감소, 실행 속도 10배 ↑
NOT IN NULL 처리 문제 NOT EXISTS 변환 결과 정확성 + 성능 향상
중첩 뷰로 인덱스 미사용  뷰 병합(MERGE VIEW) 인덱스 활용 가능
인라인 뷰에서 불필요 컬럼 SELECT 컬럼 최소화 메모리, 네트워크 전송량 절감
  • 서브쿼리는 간결하지만, 잘못 사용하면 반복 실행으로 성능 저하
  • 조인 변환, EXISTS 활용, 뷰 병합 전략으로 최적화 가능
  • 실행 계획에서 FILTER, VIEW, NESTED LOOPS 연산자를 주의 깊게 확인해야 함