세 가지는 모두 조인을 수행하는 방식이지만, 각각 다른 알고리즘과 사용 시나리오를 가집니다:
조인(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행 결과
특징:
경고 신호:
EXPLAIN에서 type: ALL이 여러 테이블에 표시rows 값이 비정상적으로 큼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)
동작 원리:
특징:
join_buffer_size로 버퍼 크기 조절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)
동작 원리:
특징:
=)에서만 사용 가능join_buffer_size와 hash_join_buffer_size로 제어세 가지 조인 방식 비교
| 특징 | 카테시안 조인 | 블록 네스티드 루프 | 해시 조인 |
|---|---|---|---|
| 조건 | 조건 없음 | 조건 있음, 인덱스 없음 | 등가 조건, 인덱스 없음 |
| 성능 | 매우 느림 | 느림 | 빠름 |
| 복잡도 | O(M × N) | O(M × N / buffer_size) | O(M + N) |
| 메모리 사용 | 적음 | 조인 버퍼 | 해시 테이블 (많음) |
| EXPLAIN Extra | - | Using join buffer (Block Nested Loop) | Using join buffer (hash join) |
| 사용 케이스 | 실수 또는 특수 분석 | 인덱스 없는 범위 조건 | 인덱스 없는 등가 조건 |
최적화 전략
해시 조인은 O(M+N) 복잡도로 가장 빠르지만, 인덱스가 있다면 Nested Loop Join이 더 빠릅니다.