SQL 레벨업이라는 도서를 정리한 내용입니다.
3장은 SQL 구문과 실행 결과, 실행 계획이 내용의 대부분을 차지하고 있지만 생략하고 결과만 정리하였습니다.
3장을 요약하자면 아래와 같습니다.
식'을 바탕으로 하는 SQL에서 '구문'을 바탕으로 하는 절차 지향형 사고를 사용하면 생기는 문제점
UNION을 사용한 조건 분기는 성능적인 측면에서 굉장히 큰 단점을 가지고 있다. 외부적으로는 하나의 SQL 구문을 사용하는 것처럼 보이지만 실제로는 여러 개의 구문이 실행하는 실행 계획으로 해석되기 때문이다.
성별이 포함되있는 여러 사람들의 정보가 담긴 테이블이 있고, 성별을 '남자'인 경우, '여자'인 경우 를 나누어 UNION을 사용해 조건 분기를 해봤다고 가정하자.
여기서 문제가 발생한다.
프로그래밍에서 "GOTO는 사용하지 않는게 좋다." 같은 말처럼 앞선 사람들의 노하우가 격언처럼 남아있는 것처럼 SQL에도 "조건 분기를 잘하는 사람은 SELECT 구만으로 조건 분기를 한다."는 말이 있다.
위 예시에서 UNION 대신에 SELECT 구에 CASE를 사용한다면 하나의 TABLE FULL SCAN만으로 실행이 된다.
UNION을 사용했을 때보다 성능이 2배 좋아졌다고 할 수 있는것이다. (캐시나 여러 요인들이 있어서 실제로 2배가 줄어드는 건 아니다.)
집계를 수행하는 SQL 구문에서 조건 분기를 사용하는 방식에 대해서 알아보자.
'지역별로 남녀 인구를 기록하는 테이블에서 지역별로 남녀의 인구 수를 구한다.'와 같은 상황에 사용한다.
'직원과 직원이 소속된 팀을 관리하는 테이블에서 해당 직원의 소속된 팀의 개수에 따라 다른 결과를 출력한다.'와 같은 상황에 사용한다. (코드 생략)
그래도 UNION 사랑하시죠?
머지 대상이 되는 SELECT 구문에서 사용하는 테이블이 다른 경우에는 UNION을 사용한다.
CASE 식을 사용할 수 없는 건 아니지만 이 경우 필요없는 결합이 발생해 성능적으로 악영향이 발생합니다.
UNION을 사용하면 인덱스를 사용하지만 이외의 경우 TABLE FULL SCAN을 사용하는 경우, UNION이 더 좋은 성능을 보여줄 수도 있다.
이 경우는 무조건 UNION을 사용하는게 효율적이지 않을 수도 있다. (관리자의 판단이 필요함)
이러한 경우 N회의 인덱스 스캔 VS 1회의 테이블 풀 스캔 중에서 어느 것이 더 빠른지에 대한 문제가 된다.
이 경우 테이블이 크고, 선택되는 레코드의 수가 적다면 UNION이 더 빠르다.
원래 UNION은 조건 분기를 위해 만들어지지 않았으므로 조건 분기를 위해 만들어진 CASE 식과 비교하면 비효율적인 것이 당연한 결과다.
그럼에도 초보자들이 UNION을 사용해 조건 분기를 하는 이유는 절차 지향형 언어에 익숙해져 있기 때문이다. 하지만 SQL의 기본적인 체계는 선언형이다.
절차 지향형 프로그래밍 언어에서 생각의 기본 단위는 '구문'이다. 하지만 SQL에서의 기본 단위는 '식'이다. 실제로 SQL 구문의 각 부분(SELECT, FROM, WHERE, GROUP BY, ...)에 작성하는 것은 모두 '식'이다.
SQL 능력을 향상시키기 위해선 선언형에 익숙해저야 한다.