Link Search Menu Expand Document

SQL의 조건 분기

UNION을 사용한 쓸데없이 긴 표현

SELECT item_name, year, price_tax_ex AS price
FROM items
WHERE year <= 2001
UNION ALL
SELECT item_name, year, price_tax_in AS price
FROM items
WHERE year >= 2002
  • 2회의 테이블 풀 스캔이 발생
  • 위와 같은 UNION을 이용한 조건 분기는 여러 개의 SELECT 문을 실행하는 실행 계획으로 해석되기 때문에 I/O 비용이 크게 증가
  • 정확한 판단 없이 SELECT 구문을 여러 번 사용할 경우 SQL 성능이 저하됨

    WHERE 구에서 조건 분기를 하는 사람은 초보자

  • WHERE 구에서 조건 분기를 하지 않고 SELECT 구에서 CASE 식을 사용하여 조건 분기
    SELECT item_name, year,
         CASE WHEN year <= 2001 THEN price_tax_ex
              WHEN year >= 2002 THEN price_tax_in END AS price
    FROM items;
    

    집계와 조건 분기

    집계 대상으로 조건 분기

  • UNION을 사용한 방법
    SELECT perfecture,
      SUM(pop_men) AS pop_men,
      SUM(pop_mom) AS pop_wom
    FROM (SELECT perfecture, pop AS pop_men, null AS pop_mom
        FROM population
        WHERE sex ='1'
        UNION
        SELECT perfecture, null AS pop_men, pop AS pop_mom
        FROM population
        WHERE sex ='2') TMP
    GROUP BY perfecture;
    
    • population 테이블 풀 스캔 2회
  • 집계의 조건 분기도 CASE 식을 사용
    SELECT perfecture, 
      SUM(CASE WHEN sex = '1' THEN pop ELSE 0 END) AS pop_men,
      SUM(CASE WHEN sex = '2' THEN pop ELSE 0 END) AS pop_wom        
    FROM population
    GROUP BY perfecture
    
    • population 테이블 풀 스캔 1회
    • 표측/표두 레이아웃 이동 문제

      집약 결과로 조건 분기

  • UNION을 사용한 방법
    SELECT emp_name, MAX(team) AS team
    FROM employees
    GROUP BY emp_name
    HAVING COUNT(*) = 1
    UNION
    SELECT emp_name, '2개를 겸무' AS team
    FROM employees
    GROUP BY emp_name
    HAVING COUNT(*) = 2
    UNION
    SELECT emp_name, '3개 이상을 겸무' AS team
    FROM employees
    GROUP BY emp_name
    HAVING COUNT(*) >= 3
    
    • employees 테이블 풀 스캔 3회
  • CASE 식을 사용한 방법
    SELECT emp_name,
      CASE WHEN COUNT(*) = 1 THEN MAX(team)
           WHEN COUNT(*) = 2 THEN '2개를 겸무'
           WHEN COUNT(*) >= 3 THEN '3개 이상을 겸무'
      END AS team
    FROM employees
     GROUP BY emp_name
    
    • employees 테이블 풀 스캔 1회

      그래도 UNION이 필요한 경우

      UNION을 사용할 수 밖에 없는 경우

  • 여러 개의 테이블에서 검색한 결과를 머지하는 경우
  • FROM 구에서 테이블을 결합하면 필요 없는 결합이 발생하여 성능적으로 악영향

    UNION을 사용하는 것이 성능적으로 더 좋은 경우

  • 테이블이 크고, WHERE 조건으로 선택되는 레코드의 수가 충분히 작다면 UNION을 사용하여 인덱스 스캔을 실행하는 경우가 더 빠를 수도 있음

    절차 지향형과 선언형

    구문 기반과 식 기반

  • 절차 지향형 프로그래밍의 기본 단위는 구문(statement)
  • 선언형 프로그래밍의 기본 단위는 식(expression)

    선언형의 세계로 도약

  • 절차 지향형 세계에서 선언형 세계로 도약하는 것이 SQL 능력 향상의 핵심