[DB] - Deep To UNION, CASE (3장) #88
Unanswered
Irisation23
asked this question in
c. Database
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
0. 들어가기에 앞서 🤔
UNION을 사용한 조건 분기는 WHERE 구만 조금씩 다른 여러 개의 SELECT 구문을 합쳐서 복수의 조건에 일치하는 하나의 결과 집합을 얻고 싶을 때 사용한다.
하지만 이는 성능적인 측면에서 굉장히 큰 단점을 가지고 있다.
외부적으로는 하나의 SQL 구문을 실행하는 것처럼 보이지만, 내부적으로는 여러 개의 SELECT 구문을 실행하는 실행 계획으로 해석되기 때문이다.
따라서 테이블에 접근하는 횟수가 많아져서 I/O 비용이 크게 늘어난다.
자 그럼 이제 UNION의 조건 분기는 좀 더 신중해야 함을 깨닫고, 언제 UNION을 사용하고 CASE를 사용할지 알아보자.
해당 3장에서 다뤄질 테이블의 구조는 아래와 같다.
1. UNION을 사용한 조건 분기
위의 테이블에서
year
필드를 사용하여, 2001년 이전과 2002년 이후의 데이터를 구분해서 가격을 출력하는 쿼리를 만든다고 가정해 보자.다음의 결과는 아래와 같다.
조건이 배타적이므로 중복 레코드가 발생하지 않는다. 그리고 정렬이 필요하지 않아, UNION ALL을 사용한다.
하지만 해당 쿼리는 문제를 안고있다.
1.1 UNION 을 사용했을 때의 실행 계획 문제
UNION을 사용한 쿼리의 성능 문제를 명확히 하기 위해 실행 계획을 살펴보면 PostgreSQL은 아래와 같은 실행 계획을 가지게 된다.
해당 결과를 보게 되면 UNION 쿼리는 Items 테이블에 2회 접근한다는 것을 알 수 있다. 그리고 TABLE ACCESS FULL이 발생하므로, 읽어들이는 비용도
테이블의 크기에 따라 선형으로 증가하게 된다.
만약 데이터 캐시에 테이블의 데이터가 있으면 어느정도 그런 증상이 완화될 수 있지만, 테이블의 크기가 커지면 캐시 히트율이 낮아지므로 비용 선택이 어려워 진다.
1.2 정확한 판단 없는 UNION 사용 회피
정확한 판단 없이 SELECT 구문 전체를 여러 번 사용해서 코드를 길게 만드는 것은 쓸데없는
테이블 접근
을 발생 시키며 SQL 성능을 나쁘게 한다.또한 물리 자원(저장소의 I/O 비용)의 소비도 불가피 하다.
2. WHERE 구에서 조건 분기는 초보자이다.
SQL에서 전해 내려오는 격언이다. "조건 분기를 WHERE 구로 하는 사람들은 초보자다. 잘 하는 사람은 SELECT 구만으로 조건 분기를 한다."
현재까지 살펴봤던 문제(TABLE ACCESS FULL 을 두번 하는 상황)은 사실 SELECT 구만으로 조건 분기를 하면 다음과 같이 최적화 할 수 있다.
해당 쿼리의 실행 계획은 아래와 같다.
기존에 일어났던 두번의 테이블 ACCESS를 한번의 ACCESS로 해결하게 되며, 성능의 개선을 이뤄낼 수 있다.
SQL 구문은 어떻게 데이터를 검색할지를 나타내는 접근 경로가 쓰여 있지 않다.
SQL 구문의 성능이 좋은지 나쁜지는 반드시 실행 계획 레벨에서 판단해야한다.
즉
EXPLAIN
키워드를 통해서 한번 체크 해주는게 좋다.4. 정리 📚
UNION을 사용한 분기는 SELECT 구문을 기본 단위로 분기하고 있다.
구문을 기본 단위로 사용하고 있다는 점에서, 아직 절차 지향형 발상을 벗어나지 못한 것이다.
반면 CASE 식을 사용한 분기는 문자 그대로 '식'을 바탕으로 하는 사고이다.
이렇게 '구문'에서 '식'으로 사고를 변경하는 것이 SQL에서의 중요한 핵심이다.
해당 키워드에서 기억할 점은 IF 조건문을 고민하며,
CASE
로는 어떻게 해결할 수 있을까에 대한 고민을 해 보는것을 추천한다.Beta Was this translation helpful? Give feedback.
All reactions