[14일차]효율적인 SQL 코드 작성하기 - JOIN시 유의할 점

김준석·2023년 12월 26일

JOIN은 연산량이 크기 때문에 JOIN 대상 테이블을 최대한 줄여서 사용하는 것이 좋다.

(WITH, 서브쿼리 등을 사용)

1. JOIN하는 테이블 간의 관계를 고려하기.

JOIN의 관계는 크게 3가지로 볼 수 있다.

1:1, 1:N, N:N

JOIN 1:1

  • [좌측 테이블] 행 하나와 [우측 테이블] 행하나가 1대1로만 대응하는 관계.
  • 예시)
    • 한명의 직원이 하나의 팀에만 소속된다고 가정했을 때 이 둘은 1대1 관계가 됨.
    • LEFT : 직원들의 인사정보 관리 테이블
    • RIGHT : 직원들의 팀별 소속 관리 테이블

JOIN 1:N

  • [왼쪽 테이블]의 행하나가 [우측 테이블] 행 여러개와 대응하는 관계
  • 예시) 고객 정보, 클릭이력의 관계
    • 고객 한명이 여러 상품을 클릭, 구매할 수 있기에 1대N 관계가 됨.
    • LEFT : 고객 정보
    • RIGHT : 클릭이력의 관계
    • (주의사항) 고객 정보를 기준으로 LEFT JOIN시 행 수가 뻥튀기 됨.
      • 고객한명이 여러번 클릭한 이력들이 행마다 지정되기 때문.
      • 클릭이력 기준으로 LEFT JOIN해야 됨.

JOIN N:N

  • [왼쪽 테이블]의 행하나가 [우측 테이블] 행 여러개와 대응하고, [우측 테이블]의 행하나가 [왼쪽 테이블] 행 여러개와 대응하는 관계
  • 예시) 대학생과 동아리의 관계
    • 학생 한명은 여러 동아리에 가입할 수 있고, 동아리에는 여러 학생들이 가입되기 때문에 n:n관계가 됨.

2. 데이터 중복이 있는지 확인하기.

데이터 특성상 중복이 발생하는 경우가 종종있다.

이를 확인하지 않고 분석을 수행하면, 큰 테이블끼리 결합하는 경우 쿼리속도가 매우 느려지게 됨.

무엇보다 의도했던 것과 다른 결과가 나올 수 있으니 주의해야된다.

예를 들어

성과지표가 [클릭 대비 많이 팔린상품], [클릭 대비 구매한 사람의 수] 이 두개가 있다고 가정해 보자.

클릭로그와 구매로그는 아래와 같은 테이블로 구성되어 있다.

1. 성과지표 : [클릭 대비 많이 팔린상품]

보조배터리를 클릭한 수는 3번이며 이중 2번 구매가 되었다.

보조배터리의 cvr = 0.67

2. 성과지표 : [클릭 대비 구매한 사람의 수]

보조배터리를 클릭한 사람 3명중 1명이 구매를 했다.

보조배터리의 cvr = 0.33

성과집계는 데이터에 따라 달라질 수 있기 때문에

중복 여부는 반드시 확인을 해줘야 된다.


3. 여러 가지 쿼리 방식을 고려하자

큰 테이블간의 JOIN 수행시 사용 방식에 따라 실행 속도 차이가 많이 날 수 있기 때문에 다양한 쿼리 방식을 고려해보자.

  • 서브쿼리, WITH 등.

예제를 통해 실행 속도를 비교해보자.

클릭 테이블의 유저 네임이

managers_v2테이블의 name컬럼 값과

중복인 정보를 가져와보자.

예제1) 서브쿼리사용.

서브쿼리를 활용하여 클릭 테이블의 유저 네임이 managers_v2테이블의 name컬럼과 중복인 데이터를 추출함.

SELECT * 
FROM clicks 
WHERE user_name IN(SELECT name FROM managers_v2);

예제2)INNER JOIN 사용

INNER JOIN을 활용해서 clicks테이블과, managers_v2 테이블의 관계를 체크하여

각 테이블의 user_name 컬럼과 name컬럼이 일치하는 값을 가져옴.

SELECT *
FROM clicks.c INNER JOIN managers_v2.m ON
c.user_name = m.name

결과) 서브쿼리는 0.03초, INNER JOIN은 5초 이상이 걸림.

이처럼 사용방식에 따라 속도차이가 많이 나게되니 여러가지 쿼리 방식을 생각하면서 코드를 짜자.

0개의 댓글