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
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은 실제 기준이 되는 왼쪽에 위치한 드라이빙 테이블을 항상 먼저 읽는 반면에 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)