[DB] Join

뚜비·2023년 8월 15일
0

DB

목록 보기
6/6

Join이란?

  • 하나의 테이블이 아닌 두 개 이상의 테이블을 묶어서 하나의 결과물을 만드는 것
  • MySQL : JOIN 쿼리 사용 / MongoDB : lookup 쿼리 사용

🤔 MongoDB 사용시 lookup은 최대한 사용하지 말아야 한다??

  • MongoDB는 조인 연산(lookup)에 대해 관계형 DB보다 성능이 떨어진다고 함.
    → 여러 벤치마크 테스트에서 알려짐
    → 여러 테이블을 조인하는 작업이 많은 경우 관계형 DB를 사용해야..


Join의 종류

내부조인(inner join)

  • 왼쪽 테이블과 오른쪽 테이블의 두 행이 모두 일치하는 행이 있는 부분만 표기
  • 두 테이블 간에 교집합

SELECT * FROM TableA A
INNER JOIN TableB B ON
A.key = B.key


왼쪽조인(left outer join)

  • 두 테이블이 일치하는 부분의 레코드와 함께 왼쪽 테이블의 모든 행을 표기
  • 만약 테이블 B에 일치하는 항목이 없으면 해당 값은 null 값이 됨

SELECT * FROM TableA A
LEFT JOIN TableB B ON
A.key = B.key


오른쪽조인(right outer join)

  • 두 테이블이 일치하는 부분의 레코드와 함께 오른쪽 테이블의 모든 행을 표기
  • 테이블 A에 일치하는 항목이 없으면 해당 값은 null 값이 됨
SELECT * FROM TableA A
RIGHT JOIN TableB B ON
A.key = B.key


합집합조인(full outer join)

  • 두 테이블이 일치하는 부분의 레코드와 일치하지 않는 모든 레코드까지 모두 표기
  • 일치하는 항목이 없으면 누락된 쪽에 null 값이 포함되어 출력

SELECT * FROM TableA A
FULL OUTER JOIN TableB B ON
A.key = B.key


Join의 원리

위의 Join의 원리는 Join의 원리를 기반으로 조인을 하는 것이다.


중첩 루프 조인(NLJ, Nested Loop Join)

  • 중첩 for문과 같은 원리로 조건에 맞는 조인을 하는 방법
  • 랜덤 접근에 대한 비용이 많이 증가하므로 대용량의 테이블에서는 사용하지 않는다.

EX) t1, t2 테이블을 조인한다 → t1 테이블에 행을 하나씩 읽고 t2 테이블에서 행을 하나씩 읽어 조건에 맞는 레코드를 찾아 결괏값을 반환

for each row in t1 matching reference key {
	for each row in t2 matching reference key{
    	if row satisfies join conditions, send to client 
    }
}
  • cf) 블록 중첩 루프 조인(BNL, Block Nested Loop)
    : 중첩 루프 조인에서 발전함
    : 조인할 테이블을 작은 블록으로 나눠서 블록 하나씩 조인

정렬 병합 조인

  • 각 테이블을 조인할 필드 기준으로 정렬하고, 정렬이 끝난 이후에 조인 작업을 수행하는 조인
  • 조인할 때 쓸 적절한 인덱스가 없고 대용량의 테이블들을 조인하고 조인 조건으로 <, > 등 범위 비교 연산자가 있을 때 쓴다.

해시 조인

  • 해시 테이블을 기반으로 조인하는 방법
  • 두 개의 테이블을 조인한다고 했을 때 하나의 테이블이 메모리에 온전히 들어간다면 보통 중첩 루프 조인보다 더 효율적
    → 메모리에 올릴 수 없을 정도로 크다면 디스크를 사용하는 비용이 발생
  • 동등(=) 조인에서만 사용할 수 있음

MySQL의 해시 조인 단계

MySQL8.0.18 release 이후 사용 가능

SELECT given_name, country_name
  FROM persons JOIN countries 
       ON persons.country_id = countries.country_id;

위의 예제를 통해 이해해보자!


1. Build 단계

  • 입력 테이블 중 하나를 기반으로 하나의 행이 저장되는 메모리 내 해시 테이블(인 메모리 해시 테이블)을 빌드하는 단계
    → 둘 중에 바이트가 더 작은 테이블(행 수가 아님)을 기반으로 해서 테이블을 빌드
    EX) 위의 예제의 경우 persons와 countries라는 테이블 중 바이트가 더 작은 countries 테이블을 기반으로 빌드
  • 조인에 사용되는 필드(조인속성)가 해시 테이블의 키로 사용
    EX) 위의 예제의 경우 countries.country_id 가 키로 사용
  • 모든 행이 해시 테이블에 저장되면 빌드 단계가 완료

2. probe 단계
업로드중..

  • 프로브 단계 동안 프로브 입력(여기서는 persons 테이블)에서 행 읽기를 시작하고, 각 행에 대해 persons.country_id의 값을 조회 키로 사용하여 행과 일치하는 해시 테이블을 조사함. 일치하는 행을 찾아서 결괏값으로 반환

🤔 해시 조인 특징

  • 각 테이블은 한 번씩만 읽게 되어 중첩해서 두 개의 테이블을 읽는 중첩 루프 조인보다 보통 성능이 더 좋음
  • 참고) 사용 가능한 메모리양은 시스템 변수 join_buffer_size에 의해 제어되며, 런타임 시 조정할 수 있음


😎참고자료

면접을 위한 CS전공지식
SQL Joins Visualizer
MySQL8 해시조인(Hash Join)

profile
SW Engineer 꿈나무 / 자의식이 있는 컴퓨터

0개의 댓글