핵심 답변
카테시안 조인은 조건 없이 모든 조합을 만들고, 블록 네스티드 루프는 버퍼를 사용한 중첩 루프 조인이며, 해시 조인은 해시 테이블로 빠르게 매칭하는 조인 방식입니다.

세 가지는 모두 조인을 수행하는 방식이지만, 각각 다른 알고리즘과 사용 시나리오를 가집니다:

알아야 할 배경 개념

조인(Join)의 기본 원리

조인은 두 테이블의 레코드를 특정 조건에 따라 결합하는 연산입니다. 조인 알고리즘은 이 결합을 얼마나 효율적으로 수행하는지에 따라 성능이 크게 달라집니다.

Nested Loop Join (기본 조인)

-- 외부 테이블의 각 행마다
FOR each row in table_A:
    -- 내부 테이블에서 매칭되는 행 찾기
    FOR each row in table_B:
        IF A.key = B.key:
            RETURN combined_row

드라이빙 테이블(외부)의 각 행마다 드리븐 테이블(내부)을 스캔하는 이중 루프 방식입니다.

드라이빙 vs 드리븐 테이블

더 깊이 파고들기

1. 카테시안 조인 (Cartesian Product)

두 테이블의 모든 가능한 조합을 생성합니다. 조인 조건이 없거나 CROSS JOIN을 사용할 때 발생합니다.

-- 카테시안 조인 예시
SELECT * FROM employees, departments;
-- 또는
SELECT * FROM employees CROSS JOIN departments;

-- employees 10행 × departments 5행 = 50행 결과

특징:

경고 신호:

2. 블록 네스티드 루프 조인 (Block Nested Loop Join)

기본 Nested Loop Join의 개선 버전으로, 조인 버퍼를 사용하여 드리븐 테이블의 스캔 횟수를 줄입니다.

SELECT * FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.name LIKE '%Kim%';

-- customers에 인덱스 없으면 Block Nested Loop 사용
-- EXPLAIN Extra: Using join buffer (Block Nested Loop)

동작 원리:

  1. 드라이빙 테이블(orders)의 여러 행을 조인 버퍼에 저장
  2. 드리븐 테이블(customers)을 한 번 스캔하면서
  3. 버퍼의 모든 행과 한 번에 비교
  4. 버퍼가 가득 차면 반복 (멀티 패스)

특징:

3. 해시 조인 (Hash Join)

MySQL 8.0.18부터 도입된 조인 방식으로, 해시 테이블을 사용하여 매우 빠르게 조인합니다.

SELECT * FROM orders o
JOIN customers c ON o.customer_id = c.id;

-- 인덱스 없을 때 자동으로 해시 조인 사용
-- EXPLAIN Extra: Using join buffer (hash join)

동작 원리:

  1. Build Phase: 작은 테이블로 해시 테이블 생성
  2. 각 행의 조인 키를 해시 함수에 넣어 해시 테이블에 저장
  3. Probe Phase: 큰 테이블을 스캔하면서
  4. 각 행의 조인 키를 해시하여 해시 테이블에서 O(1)로 매칭

특징:

세 가지 조인 방식 비교

특징 카테시안 조인 블록 네스티드 루프 해시 조인
조건 조건 없음 조건 있음, 인덱스 없음 등가 조건, 인덱스 없음
성능 매우 느림 느림 빠름
복잡도 O(M × N) O(M × N / buffer_size) O(M + N)
메모리 사용 적음 조인 버퍼 해시 테이블 (많음)
EXPLAIN Extra - Using join buffer (Block Nested Loop) Using join buffer (hash join)
사용 케이스 실수 또는 특수 분석 인덱스 없는 범위 조건 인덱스 없는 등가 조건

최적화 전략

  1. 최선: 드리븐 테이블의 조인 컬럼에 인덱스 추가 → Nested Loop Join (가장 빠름)
  2. 차선: 인덱스 없으면 해시 조인 자동 사용 (8.0.18+)
  3. 카테시안 조인 방지: 항상 조인 조건 명시
시각화
카테시안 조인 테이블 A 3 rows a1, a2, a3 × 테이블 B 4 rows b1, b2, b3, b4 = 12 combinations! 블록 네스티드 루프 드라이빙 100 rows 버퍼에 저장 조인 버퍼 드리븐 1회 스캔 → 메모리 비교 해시 조인 작은 테이블 Build 해시 함수 해시 테이블 hash(key) → row 큰 테이블 Probe → O(1) 매칭! 성능 비교 (1,000 × 1,000 rows) 카테시안 • 1,000,000 조합 생성 • 조건 없음 (실수!) → 매우 위험 블록 네스티드 • 버퍼 사용 스캔 • 패스 수 = rows/buffer → 느림 해시 조인 • 해시 테이블 O(1) • 1,000 + 1,000 연산 → 빠름! 최선: 인덱스 사용 > 해시 조인 > 블록 네스티드 > 카테시안(피하기)

해시 조인은 O(M+N) 복잡도로 가장 빠르지만, 인덱스가 있다면 Nested Loop Join이 더 빠릅니다.

함께 알면 좋은 개념