[SQL] STRAIGHT_JOIN on MySQL

by 스뎅(thDeng) on

MySQL에 STRAIGHT_JOIN이라는 희한한 join이 있다.

STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table. This can be used for those (few) cases for which the join optimizer processes the tables in a suboptimal order.

왼쪽 테이블을 먼저 읽는 join이라고 보면 될 것 같다. (ANSI SQL은 아니니 꼭 필요한 경우가 아니면 피하고 싶다.)

이런 경우에 효과가 있었다. 왼쪽 드라이빙 테이블에 비해 오른쪽 테이블의 데이터가 너무 많아 필터링 해야 하는 데이터가 많은데 정렬까지 해야 하는 경우가 있었다. 아래 테이블처럼 오른쪽 테이블(BB)이 상당히 큰데, 사실 왼쪽 테이블(AA)와 join할 때는 크게 필요 없는 데이터가 많다. 그리고 AA 테이블을 기준으로 정렬이 필요했다.

sql> SELECT * FROM
  ->   (SELECT count(1) AA FROM AA) AA,
  ->   (SELECT count(1) BB FROM BB) BB,
  ->   (SELECT count(1) 'AA and BB' FROM AA FROM BB ON AA.id = BB.aid) CC;
+---------+----------+-----------+
|      AA |       BB | AA and BB |
+---------+----------+-----------+
|  550000 |  3800000 |    550000 |
+---------+----------+-----------+

join일 때는 25초 이상 걸리는 쿼리가 straight_join은 0.01초만에 끝;;

sql> SELECT *
  -> FROM AA
  -> JOIN BB ON AA.id = BB.aid
  -> ORDER BY AA.id
  -> LIMIT 10; -- 25초 이상 걸림

sql> SELECT *
  -> FROM AA
  -> STRAIGHT_JOIN BB ON AA.id = BB.aid
  -> ORDER BY AA.id
  -> LIMIT 10; -- 0.01초면 끝

orderlimit 때문에 거대한 왼쪽 테이블(AA)이 10줄로 줄어든다. 나머지를 join하느라 고생할 필요가 없어지니 상당히 빠른 속도를 낼 것이다. 물론, 여기에 여러 다른 테이블도 함께 많이 붙어있는 상황이다.

아래처럼 STRAIGHT_JOIN을 적어주면 모든 joinSTRAIGHT_JOIN으로 동작한다.

sql> SELECT STRAIGHT_JOIN *
  -> FROM AA
  -> JOIN BB ON AA.id = BB.aid
  -> ORDER BY AA.id
  -> LIMIT 10;

참고

별도로 명시하지 않을 경우, 이 블로그의 포스트는 다음 라이선스에 따라 사용할 수 있습니다: Creative Commons License CC Attribution-NonCommercial-ShareAlike 4.0 International License