LATERAL JOIN 이란?

1. LATERAL JOIN이란?

LATERAL JOIN은 SQL에서 제공하는 특수한 JOIN 방식으로, JOIN 오른쪽의 서브쿼리에서 왼쪽 테이블의 값을 동적으로 참조할 수 있는 방법입니다.

쉽게 말해, 왼쪽 테이블의 각 행마다 오른쪽의 서브쿼리가 독립적으로 실행된다고 생각하면 이해하기 쉽습니다. 이는 각 행마다 별도의 조건이나 정렬, 제한(LIMIT) 등이 적용될 수 있어 유연성이 뛰어납니다.

예를 들어, 왼쪽에 5명의 사용자가 있고, 오른쪽에서 사용자별로 댓글 3개씩 가져오려 한다면

  • 사용자 1 → 댓글 조회 1회 실행 (3개의 댓글을 가져옴)
  • 사용자 2 → 댓글 조회 1회 실행 (3개의 댓글을 가져옴)
  • ...
  • 사용자 5 → 댓글 조회 1회 실행 (3개의 댓글을 가져옴)

→ 총 5번의 하위 SELECT 실행이 내부적으로 반복됩니다.

이러한 구조는 마치 루프(for문)처럼 동작하며, 행마다 조건이 다른 데이터를 효율적으로 가져올 수 있습니다.

추가적인 예를 들면, 쇼핑몰 서비스에서 사용자별로 "최근 주문 3건" 또는 "최근 댓글 2개"와 같은 데이터를 가져올 때 유용합니다. 기존 서브쿼리 방식은 각 사용자의 최근 주문이나 댓글을 별도의 쿼리로 가져와야 하는 복잡한 구조가 될 수 있지만, LATERAL JOIN을 사용하면 훨씬 간결하게 처리할 수 있습니다.

2. 서브쿼리와의 차이점

서브쿼리(Subquery)는 쿼리 안에 있는 또 다른 쿼리로, 보통 SELECT, WHERE, 또는 FROM 절 안에서 사용됩니다. 이 서브쿼리는 일반적으로 독립적으로 실행되며, 결과가 한 개의 값이거나 정적인 결과 집합일 때 자주 쓰입니다.

예를 들어, 사용자 한 명당 가장 최근에 쓴 댓글 하나를 가져오는 것은 서브쿼리로 충분히 할 수 있지만 사용자별로 댓글 3개씩 가져오려면, 서브쿼리를 복잡하게 작성하거나 반복해야 하기 때문에 코드가 길고 비효율적으로 변할 수 있습니다.

반면, LATERAL JOIN은 왼쪽 테이블(예: 사용자)의 각 행에 따라 오른쪽에 오는 서브쿼리가 그 행에 맞게 실행되는 방식입니다. 즉, 사용자마다 조건이 다르게 걸리고, 결과도 사용자마다 다르게 나올 수 있으며 마치 반복문 안에서 사용자별로 쿼리를 따로 실행하는 것과 비슷한 느낌입니다.

이러한 특성 때문에 LATERAL JOIN은 유저별, 게시글별, 상품별로 각각 다른 개수나 조건의 데이터를 가져올 때 유용합니다. 특히 각 행마다 상위 3개, 최신 2개 등 개별적인 제한이 필요할 때 적합 합니다.

사용 예제

  • 서브쿼리 사용 예시: 상품별 가장 최근 리뷰 1개
SELECT p.*,
  (SELECT r.review_text
   FROM reviews r
   WHERE r.product_id = p.id
   ORDER BY r.created_at DESC
   LIMIT 1) AS recent_review
FROM products p;
  • LATERAL JOIN 사용 예시: 상품별 최근 리뷰 3개
SELECT p.*, r.*
FROM products p
LEFT JOIN LATERAL (
  SELECT *
  FROM reviews r
  WHERE r.product_id = p.id
  ORDER BY r.created_at DESC
  LIMIT 3
) r ON true;

3. LATERAL JOIN 성능 유의점

LATERAL JOIN은 강력한 기능이지만, 잘못 사용하면 성능 문제가 생길 수 있습니다.

LATERAL JOIN은 왼쪽 테이블의 각 행마다 오른쪽 서브쿼리를 한 번씩 실행하게 됩니다. 즉, 왼쪽 테이블에 1,000명의 사용자가 있으면, 오른쪽 서브쿼리도 최대 1,000번 실행됩니다. 이런 반복이 많아질수록 서버에 부하가 커지게 되는데 그래서 인덱스가 잘 잡혀 있어야 효율적입니다.

쿼리 실행 계획(EXPLAIN)을 통해 실제 쿼리가 어떤 방식으로 실행되는지 확인하는 것도 중요합니다.

4. 결론

LATERAL JOIN은 SQL에서 제공하는 고급 기능 중 하나지만, 특정 상황에서는 정말 강력하고 유용한 도구가 됩니다. 특히 "왼쪽 테이블의 각 행마다 오른쪽에서 다른 데이터를 조건에 맞게 가져와야 할 때" 좋은 해결책일 수 있습니다.