8강 - UNION을 사용한 쓸데없이 긴 표현
UNION과 CASE를 사용한 조건 분기를 비교하면서, 어떤 경우에 어떤 것을 사용하는 것이 좋을지 알아보자.
UNION과 CASE 식을 사용한 조건 분기 비교
상품을 관리하는 테이블 items가 있다. 2001년까지는 세전 가격을, 2002년부터는 세후 가격을 price 필드로 표시하고자 한다.
•
UNION을 사용한 조건 분기
SELECT item_name, `year`, price_tax_ex as price
FROM items
WHERE `year` <= 2001
UNION ALL
SELECT item_name, `year`, price_tax_ex as price
FROM items
WHERE `year` >= 2002;
SQL
복사
•
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;
SQL
복사
UNION을 사용한 쿼리의 경우, 거의 같은 쿼리를 2번 실행함으로써 가독성과 성능 모두 떨어진다.
실행 계획을 보더라도 TABLE ACCESS FULL(FULL SCAN)이 2번 발생하므로, 읽어들이는 비용도 테이블의 크기에 따라 선형으로 증가한다.
9강 - 집계와 조건 분기
집계 대상으로 조건 분기
지역별로 남녀 인구를 기록하는 테이블 population이 있다. 지역별 남녀 인구를 pop_men, pop_wom으로 집계하고자 한다.
population 테이블
원하는 결과
•
UNION을 사용한 방법
SELECT prefecture, SUM(pop_men) AS pop_men, SUM(pop_wom) AS pop_wom
FROM (SELECT prefecture, pop AS pop_men, null AS pop_wom
FROM population
WHERE sex = '1' -- 남성
UNION
SELECT prefecture, null AS pop_men, pop AS pop_wom
FROM population
WHERE sex = '2') TMP -- 여성
GROUP BY prefecture;
SQL
복사
population 테이블로의 FULL SCAN 2회
•
CASE 식을 사용한 방법
SELECT prefecture,
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 prefecture;
SQL
복사
population 테이블로의 FULL SCAN 1회
CASE 식을 사용할 경우 쿼리가 간단해질 뿐 아니라 성능도 향상된다.
CASE 식 대신 IF를 사용해도 되지 않을까?
집약 결과로 조건 분기
집약 결과에 조건 분기를 수행할 수도 있다.
UNION
CASE 식
WHERE 구와 HAVING 구에서 조건 분기를 하지 말자.
10강 - 그래도 UNION이 필요한 경우
UNION을 사용해야만 하거나 성능상 UNION을 사용하는 것이 좋은 예외 상황들을 알아보자.
UNION을 사용할 수 밖에 없는 경우
머지 대상이 되는 SELECT 구문들에서 사용하는 테이블이 다른 경우, 즉 여러 개의 테이블에서 검색한 결과를 머지하는 경우 UNION을 사용해야 한다.
UNION을 사용하는 것이 성능적으로 더 좋은 경우
UNION을 사용했을 때 좋은 인덱스를 사용하지만, 이외의 경우 테이블 풀 스캔이 발생한다면 UNION을 사용하는 것이 성능적으로 더 좋을 수 있다.
ThreeElements 테이블
원하는 결과 - 특정 날짜(2013-11-01)를 값으로 갖고 있고 대칭되는 플래그 필드의 값이 T인 레코드 조회
UNION을 사용한 방법
OR을 사용한 방법
IN을 사용한 방법
3회의 인덱스 스캔 VS 1회의 테이블 풀 스캔 중 무엇이 더 빠른지는 테이블 크기와 검색 조건에 따른 선택 비율(레코드 히트율)에 따라 달라진다.
테이블이 크고, WHERE 조건으로 선택되는 레코드의 수가 충분히 작다면 UNION(과 OR)이 더 빠르다.
11강 - 절차 지향형과 선언형
예외적인 몇 가지 상황을 제외하면 UNION을 사용하지 않는 것이 성능적으로도 좋고 가독성도 좋다. 조건 분기를 위해 만들어진 CASE 식을 사용하자.
절차 지향형 프로그래밍 언어에서의 기본 단위는 구문(statement)이지만, SQL에서의 기본 단위는 식(expression)이다. SQL 구문의 각 부분(SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY)에 작성하는 것은 모두 식이다. 익숙해지자.