MySQL에서 STRAIGHT_JOIN이란?
MySQL의 STRAIGHT_JOIN은 INNER JOIN 또는 JOIN과 동일하게 작동하며, 일치하는 행만 반환합니다. 하지만 결정적인 차이가 있습니다. 바로 옵티마이저가 테이블 조인 순서를 변경하지 못하도록 강제한다는 점입니다.
일반적인 JOIN 구문에서 MySQL 옵티마이저는 성능 최적화를 위해 테이블을 읽는 순서를 임의로 재배열할 수 있습니다. 반면 STRAIGHT_JOIN을 사용하면 쿼리에 작성된 테이블 순서 그대로 왼쪽 테이블부터 읽어 조인을 수행합니다. 이를 통해 개발자가 의도한 실행 계획을 강제할 수 있어, 특정 상황에서 성능 문제를 해결하는 데 유용합니다.
예제용 테이블 생성하기
STRAIGHT_JOIN의 동작을 확인하기 위해 외래 키 제약 조건으로 연결된 두 개의 테이블을 먼저 만들겠습니다.
1. 첫 번째 테이블(자식 테이블) 생성
mysql> CREATE table ForeignTableDemo -> ( -> Id int, -> Name varchar(100), -> FK int -> ); Query OK, 0 rows affected (0.47 sec)
2. 두 번째 테이블(부모 테이블) 생성
mysql> CREATE table PrimaryTableDemo -> ( -> FK int, -> Address varchar(100), -> primary key(FK) -> ); Query OK, 0 rows affected (0.47 sec)
3. 외래 키 제약 조건 추가
mysql> ALTER table ForeignTableDemo add constraint FKConst foreign key(FK) references PrimaryTableDemo(FK); Query OK, 0 rows affected (1.54 sec) Records: 0 Duplicates: 0 Warnings: 0
데이터 삽입 및 조회
먼저 부모 테이블인 PrimaryTableDemo에 레코드를 삽입합니다.
mysql> INSERT into PrimaryTableDemo values(1,'US'); Query OK, 1 row affected (0.10 sec) mysql> INSERT into PrimaryTableDemo values(2,'UK'); Query OK, 1 row affected (0.14 sec) mysql> INSERT into PrimaryTableDemo values(3,'Unknown'); Query OK, 1 row affected (0.08 sec)
PrimaryTableDemo 조회 결과
+----+---------+ | FK | Address | +----+---------+ | 1 | US | | 2 | UK | | 3 | Unknown | +----+---------+ 3 rows in set (0.00 sec)
다음으로 자식 테이블인 ForeignTableDemo에 레코드를 삽입합니다.
mysql> INSERT into ForeignTableDemo values (1,'John',1); Query OK, 1 row affected (0.20 sec) mysql> INSERT into ForeignTableDemo values (2,'Bob',2); Query OK, 1 row affected (0.27 sec)
ForeignTableDemo 조회 결과
+------+------+------+ | Id | Name | FK | +------+------+------+ | 1 | John | 1 | | 2 | Bob | 2 | +------+------+------+ 2 rows in set (0.00 sec)
STRAIGHT_JOIN 쿼리 실행하기
이제 STRAIGHT_JOIN을 사용하여 두 테이블에서 일치하는 행만 조회해 보겠습니다.
mysql> SELECT ForeignTableDemo.Id, ForeignTableDemo.Name, PrimaryTableDemo.Address -> from ForeignTableDemo -> STRAIGHT_JOIN PrimaryTableDemo -> on ForeignTableDemo.FK = PrimaryTableDemo.FK;
실행 결과
+------+------+---------+ | Id | Name | Address | +------+------+---------+ | 1 | John | US | | 2 | Bob | UK | +------+------+---------+ 2 rows in set (0.00 sec)
결과를 보면 FK 값이 서로 일치하는 행만 반환된 것을 확인할 수 있습니다. 부모 테이블에 있는 'Unknown'(FK=3)에 해당하는 데이터는 자식 테이블에 없기 때문에 결과에 포함되지 않았습니다.
STRAIGHT_JOIN 활용 시 주의사항
- 조인 순서 강제: FROM 절에 먼저 작성된 테이블이 드라이빙 테이블(외부 테이블)로 지정됩니다.
- 성능 저하 가능성: 잘못된 테이블 순서를 지정하면 옵티마이저의 최적화 기회를 차지 않아 오히려 성능이 나빠질 수 있습니다.
- 사용 시점: EXPLAIN으로 실행 계획을 분석한 후, 옵티마이저가 비효율적인 조인 순서를 선택하는 경우에만 신중하게 사용하는 것이 좋습니다.