real mysql - left join 튜닝

리아코파이리·2024년 7월 29일

mysql

목록 보기
6/6

예시 - 전체 유저 목록을 조회하는데, 3번 쿠폰을 가진 유저들에 대해서 쿠폰 사용여부를 같이 조회

CREATE TABLE USER(
	id int NOT NULL AUTH_INICREMENT,
	PRIMARY KEY(id)
);
CREATE TABLE USER_COUPON(
	user_id int NOT NULL,
    coupon_id int NOT NULL,
    
    PRIMARY key (user_id, coupon_id)
    KEY idx_counpon_id (coupon_id)
);

SELECT u.id, u.name, uc.coupon_id, uc.use_yn
FROM user u
LEFT JOIN user_coupon uc ON uc.user_id = u.id AND uc.coupon_id = 3

LEFT JOIN 을 잘못사용하면 JOIN 처럼 결과 반환

USER - 30000rows
USER_COUPON - 3000rows coupon_id = 1 (1000) coupon_id = 2 (1000) coupon_id = 3 (1000)


SELECT u.id, u.name, uc.coupon_id, uc.use_yn
FROM user u
LEFT JOIN user_coupon uc ON uc.user_id = u.id AND uc.coupon_id = 3

-> 30000rows

-> 변환


SELECT u.id, u.name, uc.coupon_id, uc.use_yn
FROM user u
LEFT JOIN user_coupon uc ON uc.user_id = u.id
WHERE uc.coupon_id = 3

-> 1000rows

LEFT JOIN 에서는 Table 끼리의 데이터를 연결하는 역할을 수행했던 반면에 WHERE 에서는 실제 결과로 반환되는 데이터를 필터링하는 역할을 수행

옵티마이저가 자동적으로 Inner Join 으로 변경

LEFT JOIN 예시

left join 왼쪽에 있는 테이블을 일반적으로 아우터 테이블, 드라이빙 테이블,
오른쪽에는 이너테이블 드리븐 테이블이라고 한다.

Left join은 실제 기준이 되는 왼쪽에 위치한 드라이빙 테이블을 항상 먼저 읽는 반면에 inner join은 조인에 참여하는 테이블들의 교집합 데이터를 결과로 반환하는 것이므로 처리순서가 항상 고정되는것이 아니라 옵티마이저에 의해 최적화되면서 좀 더 효율적으로 처리될 수 있도록 테이블 접근 순서가 변경될 수 있다.

Left join을 하지 않아도 결과가 동일한 경우에는, 불필요한 Left JOIN은 제거해서 사용


SELECT COUNT(*)
FROM user u
LEFT JOIN user_coupon uc ONB uc.user_id = u.id AND uc.coupon_id = 3;

30000rows (0.07sec)

SELECT COUNT(*)
FROM user u

30000rows (0.00sec)

정리

  • Left join 을 사용하고자 한다면 드라이븐 테이블 컬럼의 조건(조인 조건)은 반드시 ON절에 명시해서 사용(Is null 조건은 예외)
  • left join과 inner join은 결과 데이터 및 쿼리 처리 방식 등이 매우 다르므로 필요에 맞게 올바르게 사용하는 것이 중요
  • left join 쿼리에서 COUNT를 사용하는 경우 left join이 굳이 필요하지 않다면 join 제거
  • join ON절은 조인 전의 각 테이블에 있는 데이터에 조건을 거는 것이고 WHERE 절은 조인 후의 데이터에 조건을 거는것 참조

https://www.inflearn.com/community/questions/649682/inner-join-%EA%B3%BC-left-join%EC%9D%98-on-%EC%A1%B0%EA%B1%B4-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EC%A7%88%EB%AC%B8

profile
https://github.com/protossking

0개의 댓글