LATERAL JOIN

신연우·2025년 6월 29일

WIL

목록 보기
21/21

회사에서 MySQL 버전을 8.0 버전대로 올리면서 LATERAL JOIN을 사용할 수 있게 되었습니다.
당장 해당 조인을 사용해야 하는 요구사항을 받지는 못했지만, 어떤 방식으로 동작하는지를 미리 알아보고자 하였습니다.

LATERAL JOIN

조인에서 outer 테이블에 있는 각 행을 기준으로 inner 서브쿼리를 실행할 수 있도록 해주는 기능입니다.
일반적인 JOIN과는 다르게 outer 테이블의 행의 정보를 inner 서브쿼리에서 참조할 수 있다는 특징이 있습니다.

예시

만약, 고객별로 최근 주문 1건을 조회하고 싶은 상황이라면 어떻게 쿼리를 작성해야 할까요?

SELECT
    u.id,
    u.name,
    (SELECT o.id FROM orders o WHERE o.customer_id = u.id ORDER BY o.created_at DESC LIMIT 1) as order_id,
    (SELECT o.created_at FROM orders o WHERE customer_id = u.id ORDER BY o.created_at DESC LIMIT 1) as ordered_datetime
FROM users u;

위와 같이 작성을 해야 합니다. SELECT 절에 서브쿼리를 반복적으로 사용하는 것은 가독성도 떨어집니다. 또한, 서브쿼리의 SELECT 절만 다르고 나머지는 동일한 쿼리를 users 행 하나마다 두 번씩 매번 실행해야 하는 점은 성능상 비효율적일 수 있습니다.

이를 LATERAL JOIN으로 다음과 같이 개선할 수 있습니다.

SELECT
    u.id,
    u.name,
    o.id as order_id,
    o.created_at as ordered_datetime
FROM users u
LEFT JOIN LATERAL (
    SELECT
        o.id,
        o.created_at
    FROM orders o
    WHERE o.customer_id = u.id
    ORDER BY o.created_at DESC
    LIMIT 1
) o ON TRUE;

장점

위에서 LATERAL JOIN으로 개선한 쿼리는 기존 쿼리에 비해 다음과 같은 장점을 가지고 있습니다.

  1. 서브쿼리를 한 번만 계산합니다.
    기존 쿼리는 users 행을 하나 읽을 때마다 두 번의 서브쿼리를 실행해야 했습니다.
    하지만 개선한 쿼리는 users 행을 하나 읽을 때마다 한 번의 서브쿼리를 실행합니다.
  1. 가독성 향상
    부가적이긴 하지만 서브 쿼리를 JOIN 절에 뭉침으로서 평소 익숙한 SQL 형태로 변형되어 가독성이 좋아졌습니다.

주의할 점

LATERAL JOIN은 결국 행을 하나 찾을 때마다 서브쿼리를 실행해야 하는 구조입니다.
기존 서브쿼리 JOIN과는 다르게 외부 행마다 서브쿼리를 실행하므로 결과가 항상 동적으로 생성됩니다.
따라서 극단적으로 레코드 단위마다 서브 쿼리 결과를 위한 임시 테이블 생성이 진행될 수 있습니다.
무분별하게 사용하는 경우 성능 문제가 발생할 수 있으므로 주의해서 사용해야 합니다.

profile
남들과 함께하기 위해서는 혼자 나아갈 수 있는 힘이 있어야 한다.

0개의 댓글