학습주제
- 효율적인 SQL 코드 작성하기
- 테이블을 집합으로 생각하기
- *, % 사용 지양하기
- 데이터 타입 잘 확인하기
- JOIN 시 유의할 점
- 가독성 높이기
주요 메모 사항 소개
- 테이블을 집합으로 생각한다.
- 최대한 작게 만들어 놓고 JOIN 한다.
- 즉 WHERE 절을 이용하여 최대한 필터링 하는것이 효율적이다.
WITH customer as ( SELECT customer_id, customer_name, customer_tier FROM Customers WHERE customer_id = 1 -- <- 처럼 WHERE문을 사용하여 최대한 필터링을 거친 후 -- 사용하는 것이 좋다 ), order_info as ( SELECT customer_id, order_id, amount FROM Orders WHERE customer_id = 1 ) SELECT c.customer_id, customer_name, customer_tier, count(distinct order_id) as odr_cnt, sum(amount) as total_purchase FROM customer c INNER JOIN order_info o on c.customer_id = o.customer_id GROUP BY 1, 2, 3 ORDER BY 4 DESC --better ----------------------------------------------------------------------- WITH customer as ( SELECT customer_id, customer_name, customer_tier FROM Customers ), order_info as ( SELECT customer_id, order_id, amount FROM Orders WHERE customer_id = 1 ) SELECT c.customer_id, customer_name, customer_tier, count(distinct order_id) as odr_cnt, sum(amount) as total_purchase FROM customer c INNER JOIN order_info o on c.customer_id = o.customer_id GROUP BY 1, 2, 3 ORDER BY 4 DESC
- *, % 사용 지양한다.
- LIMIT 걸고 조회한다.
- 파티션이 있는 테이블인지 확인하고, 파티션을 필터 조건으로 걸고 조회한다.
- 칼럼 수가 많은 테이블을 조회할 때 SELECT * 사용 지양한다.
- 위의 사진 처럼 SELECT 문에 본인이 필요한걸 찾아서 적어주는게 효율적 입니다. - LIKE 사용 시 % 제한적으로 사용한다.
SELECT product_id, name FROM products WHERE name LIKE '23FW%' LIMIT 10 ------------------------------ SELECT product_id, name FROM products WHERE name LIKE '23FW__' -- <- 이런식으로 % 사용을 지양합니다. LIMIT 10
- LIMIT 걸고 조회한다.
- 데이터 타입 잘 확인하기
- 묵시적 형변환 : 비교하고자 하는 값이 서로 다른 타입일때, DB가 알아서 TYPE을 맞춘 후 비교하는 것
- 형변환에 걸리는 시간만큼 쿼리가 비효율적이 된다.
- 쿼리가 복잡해지면 문제 해결 시 시간이 오래 걸린다. - 비교 연산자를 쓸 때 타입을 확인한다.
비교 연산자 사용시 type을 먼저 확인한 후 맞는 type으로 비교하여 묵시적 형변환을 예방한다. - WHERE 절에서 왼쪽 컬럼에 함수 적용 지양한다.
위의 코드는 문제가 없지만 DATE_FORMAT 함수를 date절에 사용하면 문제가 발생한다. 이유는 WHERE 절에서 컬럼쪽에 함수를 사용할 경우 index (데이터 읽기속도에 연관) 사용 불가능하다. 또한 큰 테이블 컬럼에 함수를 적용하면 수행시간만큼 컬럼이 무거워 진다.
- 묵시적 형변환 : 비교하고자 하는 값이 서로 다른 타입일때, DB가 알아서 TYPE을 맞춘 후 비교하는 것
- JOIN 시 유의할 점
- 1. JOIN 하는 테이블 간의 관계를 고려한다.
https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_modelE-R 모델을 잘 파악해야합니다. - 데이터 중복이 있는지 확인한다.
- 큰 테이블끼리 결합하면 속도가 느려지고, 결과 값이 달라질 수 있다. - 여러가지 쿼리 방식을 고려하자
위의 3가지 코드는 전부 동일한 값을 출력하는 코드 입니다. 이중 2번 코드가 가독성이 좋고 제일 빠르나 상황에 따라 맞게 사용하면 좋을 것 같습니다.SELECT user_name, product_id FROM ( SELECT user_name, clk_index, product_id, row_number() over(PARTITION BY user_name ORDER BY clk_index ASC) as rownum FROM clikcs ) WHERE rownum = 1 -------------------------------------------- WITH clk as ( SELECT user_name, product_id, clk_index FROM clicks ), mini as ( SELECT user_name, min(clk_index) as min_inx FROM clicks GROUP BY 1 ) SELECT clk.user_name, clk.product_id FROM clk INNER JOIN mini ON clk.user_name = mini.user_name AND clk.clk_index = min_idx --------------------------------------------- SELECT c.user_name, product_id FROM clicks c INNER JOIN( SELECT user_name, min(clk_index) as min_idx FROM clicks GROUP BY 1 ) g ON c.user_name = g.user_name AND c.clk_index = min_idx
- 1. JOIN 하는 테이블 간의 관계를 고려한다.
- 가독성 높이기
- 서브쿼리 보다는 WITH 구문이 가독성이 좋다.
- WITH 절을 사용할 때, 각 블록 이름을 잘 지정하자
- 쿼리가 복잡해 지면 중간중간 주석을 작성하자.
이런식으로 WITH 문과 주석을 활용하여 가독성을 높이면 좋습니다.WITH odr_cnt as ( -- 고객별 구매 수 SELECT c.customer_id, count(distinct order_id) as odr_cnt, sum(amount) as total_purchase FROM Customers c INNER JOIN Orders o on c.customer_id = o.customer_id GROUP BY 1 ORDER BY 2 DESC )
공부하며 어려웠던 내용
- JOIN을 사용할때 효율성을 높히려면 상당히 고려할게 많다는 것을 느꼈다.
위의 내용을 토대로 깔끔한 코드 작성을 연습해야겠다.
반응형
'데이터분석' 카테고리의 다른 글
22. SQL 코드 작성 (0) | 2023.12.29 |
---|---|
21. 관계형 데이터 베이스, 데이터 웨어하우스 (1) | 2023.12.18 |
13. 데이터 타입 (1) | 2023.12.06 |
12. SQL문 (1) | 2023.12.05 |
11. SQL 과 RDB (1) | 2023.12.04 |