[SQL] 구문에서 식으로 사고하기

baekdata·2021년 9월 24일
0

SQL

목록 보기
1/3
post-thumbnail

이 글은 SQL 레벨업(한빛 미디어, 미크)를 참고하여 작성하였습니다.

SQL을 잘 사용하기 위해서는 "구문"에서 "식"으로 사고를 전환해야 한다고 한다.

아래에 작성되어 있는 쿼리는 동일한 결과를 출력한다.

그러나, 두 가지의 쿼리는 성능 상 큰 차이를 보이고 있다. 어떤 쿼리가 좋은 쿼리일까?

-- 쿼리1. 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 > 2001 ;

-- 쿼리2. 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 ; 

2개의 쿼리는 아래의 조건을 만족하는 데이터를 출력한다.

(1) 2001년을 포함하여 그 이전은 세금을 매기기 전 가격을 출력한다.
(2) 2002년을 포함하여 그 이후는 세금을 매긴 가격을 출력한다.

이를 위해, 1번 쿼리는 UNION을 사용하여 조건 분기를 했고 2번 쿼리는 SELECT 구문에서 CASE 식을 사용하여 조건 분기를 수행했다.

결론부터 이야기하면, 2번 쿼리가 성능 상 우위에 있다. 이유는 다음과 같다.

먼저, 1번 UNION을 사용하여 조건 분기를 한 케이스를 보면 쿼리가 불필요하게 길어져있다. 쿼리가 긴 것 자체는 문제가 크지 않지만, 성능에 영향을 주는 것은 실행 계획을 보면 알 수 있다.

실행 계획을 보게되면, 1번 쿼리는 items 테이블에 Table Access Full 방식으로 2회 접근하고 있다.

반면, 2번 CASE를 이용한 쿼리는 items 테이블에 1회만 접근하며 가독성도 좋다.

SQL 격언에 이런 말이 있다고 한다.

"조건 분기를 WHERE 구로 하는 사람은 초보다.
잘 하는 사람은 SELECT 구만으로 조건 분기를 한다"

이 말을 뜯어보면, "구문"에서 "식"으로 사고를 전환해야 성능에 우위에 있는 쿼리를 작성하게 된다는 말로 풀이된다.

위 예시에서 확인한 문제를 실무에서 받게되면, 직관적으로 떠오르는 방법은 1번 쿼리에 가깝다. WHERE 절의 조건을 바꿔가며, 여러개의 SELECT 구문을 합쳐서, 복수 조건에 일치하는 하나의 결과 집합을 얻고 싶을 때 사용하게 된다.

그러나, 앞서 살펴보았듯이 UNION을 이요한 조건 분기는 외부적으로는 하나의 SQL 실행처럼 보이지만, 내부적으로는 여러개의 SELECT 구문을 실행하는 실행 계획을 가지게 되고 이에 따라 테이블 접근 횟수 증가로, I/O 비용이 크게 늘어나게 된다.

따라서, 쿼리를 작성할 때 아래와 같은 생각과 습관을 가지도록 노력하면 좋겠다.

  • UNION을 사용한 분기는 SELECT "구문"을 기본 단위로 분기하고 있는 점에서, 아직 절차 지향형의 발상을 벗어나지 못한 방법임
  • 이와 달리, CASE "식"을 이용한 분기는 문자 그대로 "식"을 바탕으로 하는 사고임
  • "구문"에서 "식"으로 사고를 변경하는 것이 SQL을 잘 사용하는 열쇠임
  • 스스로 "문제를 절차 지향형 언어로 해결한다면, 어떤 IF 조건문을 사용해야 할까?"라고 사고 할 때마다 "이것을 SQL의 CASE로는 어떻게 해결할 수 있을까?"라고 꾸준히 의식하고 사용하는 습관을 가지기
profile
글쓰는 데이터 분석가

0개의 댓글