
난 이전까지 쿼리로 코딩을 했던걸까..
최근 SQL 레벨업 책을 읽고 힌트를 얻어 union을 case로 처리하고 서브쿼리 개수를 10% 줄였다. 이 책은 단순히 문법을 사전처럼 나열한 것이 아니라 쿼리 접근법에 대해서 이야기하는 것이 좋았다.
코딩과 쿼리 작성은 접근법이 다르다.
코딩은 조건 분기를 문장 단위로 하지만, 쿼리는 식으로 조건 분기를 한다.
WHERE 절에 갈 쿼리가 SELECT 문에서 CASE로 최적화될 수 있다.
UNION을 조건 분기를 위해 사용하다면 불필요한 테이블 접근을 발생시키며 저장소의I/O비용도 늘어난다.
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의 불필요한 사용을 비판한다.
UNION도 당연히 필요하다.
연관성이 없는 테이블의 결과 혹은 보여줄 라벨 리스트(통계)를 수동으로 만들어야 할 때는 UNION을 써야 한다.
잘 사용된 UNION은 OR,IN 조건절을 가뿐히 이긴다.
이 과정에서 MAX()와 같은 집약 함수가 필요할 수 있다.
SELECT id,
MAX(CASE WHEN data_type = 'A' THEN data_1 ELSE NULL END) AS data_1,
... 중략
FROM NonAggTbl
GROUP BY id;
집약테이블이 작다면 뷰로 만드는 방법도 있다.
이 과정에서 집합과 요소를 혼동하지 않도록 한다.
SQL은 실행 시간에 관계없이 일정한 오버헤드가 필요한데, 반복계로 실행하면 오버헤드 비용이 그만큼 소요된다.
작은 일거리 100개(반복계)보다 큰 일거리 1개(포장계)가 더 낫다.
SQL은 반복을 대신해서 CASE와 윈도우 함수를 사용한다.
상관서브쿼리 대신 윈도우 함수의
PARTITION BY구과ORDER BY구를 사용할 수 있다.
'구문'에서 '식'으로 사고를 변경하는 것이 SQL을 마스터하는 열쇠 중 하나입니다. 어떻게 SQL의 CASE로 해결할 수 있을까?
SQL의 성능은 저장소의 I/O를 얼마나 감소시킬 수 있을지가 열쇠
이 글은 사고의 전환 위주로 적었지만 실제로 좋은 예제들이 많이 담겨있다
SQL은 뚱뚱하고 무식해 보이는 CASE가 더 좋은 성능을 가져다 주는 것 같다. (p.185 예제)