RDBMS에서 조인은 단순히 두 개의 테이블을 연결하는 개념이 아닙니다. SQL Server는 내부적으로 다음과 같은 3가지 방식 중 하나로 조인을 수행합니다:
각 방식은 데이터의 양, 정렬 여부, 인덱스 유무 등에 따라 선택되며, 옵티마이저가 자동으로 결정하거나 OPTION 힌트를 통해 강제할 수도 있습니다.
BaseballData 데이터베이스를 사용합니다.players, salaries, teamsSELECT *
FROM players AS p
INNER JOIN salaries AS s
ON p.playerID = s.playerID;
Merge Join으로 표시됨SELECT TOP 5 *
FROM players AS p
INNER JOIN salaries AS s
ON p.playerID = s.playerID;
TOP 키워드 등으로 부분 범위 검색을 수행할 때 사용됨Nested Loops로 표시됨SELECT *
FROM salaries AS s
INNER JOIN teams AS t
ON s.teamID = t.teamID;
Hash Match로 표시됨NL 조인은 이름 그대로 중첩된 루프를 돌면서 외부 테이블의 한 행마다 내부 테이블을 탐색하는 방식입니다.
외부(OUTER) 테이블을 순차적으로 순회하며
내부(INNER) 테이블에 랜덤 액세스하는 방식입니다.
for (외부테이블의 row in TableA)
{
for (내부테이블의 row in TableB)
{
if (rowA.key == rowB.key)
조인 결과에 포함
}
}
NL 조인의 개념은 프로그래밍에서 이중 루프 구조와 동일합니다.
foreach (Player p in players)
{
foreach (Salary s in salaries)
{
if (p.playerId == s.playerId)
{
result.Add(p.playerId);
break;
}
}
}
Dictionary<int, Salary> salariesDict = ...
foreach (Player p in players)
{
if (salariesDict.TryGetValue(p.playerId, out var s))
{
result.Add(p.playerId);
}
}
List → Dictionary로 변경SELECT *
FROM players AS p
INNER JOIN salaries AS s
ON p.playerID = s.playerID
OPTION(LOOP JOIN);
salaries 테이블: Clustered Index Scan (외부 테이블)players 테이블: Index Seek + Key Lookup (내부 테이블)SELECT *
FROM players AS p
INNER JOIN salaries AS s
ON p.playerID = s.playerID
OPTION(FORCE ORDER, LOOP JOIN);
FORCE ORDER 힌트를 통해 FROM 절 순서 강제SELECT TOP 5 *
FROM players AS p
INNER JOIN salaries AS s
ON p.playerID = s.playerID;
if (result.Count >= 5) break; 와 동일