Data Engineering/Spark

[Spark] 스파크 조인

쟈누이 2023. 11. 22. 23:24
반응형

8.1 조인 표현식

#python3
DF.join( JoinDF , JoinExpression, (joinType) )
 - JoinDF : 조인 대상
 - JoinExpression : 조인 표현식(조건)
 - joinType : 조인 타입( 생략가능 / defaultValue : inner )
  • 왼쪽, 오른쪽 데이터 셋에 있는 하나 이상의 키값을 비교하고 왼쪽 데이터 셋과 오른쪽 데이터 셋의 결합 여부를 결정하는 조인 표현식의 평가 결과에 따라 두 개의 데이터 셋을 조인
  • 가장 많이 사용하는 조인식은 동등 조인(equi-join)
  • 더 복잡한 조인 정책도 지원함

8.2 조인 타입

내부 조인(inner join) 왼쪽, 오른쪽 데이터 셋에 키가 있는 로우를 유지

외부 조인(outer join) 왼쪽이나 오른쪽 데이터 셋에 키가 있는 로우를 유지
왼쪽 외부 조인(left outer join) 왼쪽 데이터 셋에 있는 키가 로우를 유지
오른쪽 외부 조인(right outer join) 오른쪽 데이터 셋에 있는 키가 로우를 유지
왼쪽 세미 조인 (left semi join) 왼쪽 데이터 셋의 키가 오른쪽 데이터 셋에 있는 경우 키가 일치하는 왼쪽 데이터 셋만 유지
왼쪽 안티 조인 (left anti join) 왼쪽 데이터 셋의 키가 오른쪽 데이터셋에 없는 경우에는 키가 일치하지 않는 왼쪽 데이터셋만 유지
자연 조인 (natural join) 두 데이터셋에서 동일한 이름을 가진 컬럼을 암시적으로(implicit) 결합하는 조인을 수행
교차 조인 (cross join) 왼쪽 데이터셋의 모든 로우와 오른쪽 데이터셋의 모든 로우를 조합

8.3 내부 조인

  • 데이터 프레임이나 테이블에 존재하는 키를 평가
  • true 로 평가되는 로우만 결합
// 스칼라 코드
val joinExpression = person.col("graduate_program") === graduateProgram.col("id")
  • 두 데이터 프레임 모두에 키가 존재하지 않으면 결과 데이터프레임을 볼 수 없음
  • 내부 조인은 기본 조인 방식이므로 join 표현식에 왼쪽 데이터 프레임과 오른쪽 데이터 프레임을 지정하기만 하면됨
person.join(graduateProgram, joinExpression).show()
  • join 매서드의 세번째 파라미터로 저인 타입을 명확하게 지정할 수 있음
val joinType = "inner"
person.join(graduateProgram, joinExpression, joinType).show()

8.4 외부 조인

  • 데이터 프레임이나 테이블에 존재하는 키를 평가하여 참이나 거짓으로 평가한 로우를 포함한다.
  • 왼쪽이나 오른쪽 데이터프레임에 일치하는 로우가 없다면 스파크는 해당 위치에 null 삽입
joinType = "outer"
person.join(graduateProgram, joinExpression, joinType).show()

8.5 왼쪽 외부 조인

  • 데이터프레임이나 테이블에 존재하는 키를 평가
  • 왼쪽 데이터프레임의 모든 로우와 왼쪽 데이터프레임과 일치하는 오른쪽 데이터프레임의 로우를 함께 포함
  • 오른쪽 데이터 프레임에 일치하는 로우가 없다면 스파크는 해당 위치에 null 을 삽입
joinType = "left_outer"
gratuateProgram.join(person, joinExpression, joinType).show()

8.6 오른쪽 외부 조인

  • 오른쪽 데이터프레임의 모든 로우와 오른쪽 데이터 프레임과 일치하는 왼쪽 데이터 프레임의 모든 로우를 함꼐 포함
  • 왼쪽 데이터 프레임에 일치하는 로우가 없다면 스파크는 해당 위치에 null 을 삽입
joinType = "reight_outer"
person.join(graduateProgram, joinExpression, joinType).show()

8.7 왼쪽 세미 조인

  • 오른쪽 데이터프레임의 어떠한 값도 포함하지 않기 때문에 다른 조인타입과 약간 다름
  • 두번째 데이터프레임은 값이 존재하는지 확인하기 위해 값만 비교하는 용도
  • 값이 존재한다면 왼쪽 데이터프레임에 중복 키가 존재하더라도 해당 로우는 결과에 포함
  • 왼쪽 세미 조인은 기존 조인기능과 달리 데이터 프레임의 필터 정도
joinType = "left_semi"
graduateProgram.join(person, joinExpression, joinType).show()

8.8 왼쪽 안티 조인

  • 세미 조인의 반대 개념
  • 오른쪽 데이터프레임의 어떤 값도 포함하지 않음
  • 두번째 데이터프레임은 값이 존재하는지 확인하기 위해 값만 비교하는 용도
  • 두번째 데이터프레임에서 관련된 키를 찾을 수 없는 로우만 결과에 포함
  • sql 의 not in 과 같은 스타일의 필터로 볼 수 잇음
joinType = "left_anti"
graduateProgram.join(person, joinExpression, joinType).show()

8.9 자연 조인

  • 조인하려는 컬럼을 암시적으로 추정
  • 일치하는 컬럼을 찾고 그 결과를 반환

8.10 교차 조인(카테시안 조인)

  • 조건절을 기술하지 않은 내부 조인
  • 왼쪽 데이터 프레임의 모든 로우를 오른쪽 데이터프레임의 모든 로우와 결합
  • 엄청난 수의 로우를 가진 데이터 프레임이 생성될 수 있음
  • 반드시 키워드를 이용해 교차 조인을 수행한다는 것을 명시적으로 선언해야함
joinType = "cross"
graduageProgram.join(person, joinExpression, joinType).show()

8.11 조인 사용시 문제점

  • 조인을 수행할 때 가장 까다로운 것 중 하나는 데이터프레임에서 중복된 컬럼 명을 다루는 것
  • 데이터 프레임의 각 컬럼은 스파크 sql 엔진인 카탈리스트 내 고유 아이디가 있음
  • 카탈리스트는 내부에서만 사용하므로 직접 참조 불가
  • 컬럼명이 존재하는 데이터 프레임을 사용할 때 특정 컬럼을 참조하기 매우 어려움
- 조인에 사용할 데이터 프레임의 특정 키가 동일한 이름을 가지며, 
  키가 제거되지 않도록조인 표현식에 명시하는 경우
- 조인 대상이 아닌 두개의 컬럼이 동일한 이름을 가지는 경우

1) 해결방법 1 : 다른 조인 표현식 사용

  • 가장 쉬운 조치 중 하나는 불리언 형태의 조인 표현식을 문자열이나 시퀀스 형태로 바꾸는 것
person.join(gradPragramDupe, "graduate_program").select("graduate_program).show()

2) 해결 방법 2 : 조인후 컬럼 제거

  • 조인 후 문제가 되는 컬럼을 제거
  • 조인시 동일한 키 이름을 사용하거나 원본 데이터프레임에 동일한 컬럼명이 존재하는 경우 사용 가능
person.join(gradProgramDupe, joinExpr).drop(person.col("graduate_program"))\\
.select("graduate_program").show()

3) 해결 방법 3 : 조인 전 컬럼명 변경

  • 조인 전에 컬럼명을 변경하면 이런 문제를 완전히 회피 가능
val gradProgram3 = graduateProgram.withColumnRenamed("id", "grad_id")
val joinExpr = person.col("graduate_program) === gradProgram3.col("grad_id")person.join(gradProgram3, joinExpr).show()
person.join(gradProgram3, joinExpr).show()

8.12 스파크의 조인 수행 방식

  • 조인 수행방식을 이해하기 위해서는 실행에 필요한 두가지 핵심 전략을 이해해야함

1) 네트워크 통신 전략

  • 두가지 클러스터 통신 방식 활용

셔플 조인(큰테이블과 큰테이블 조인 good)

  • 노드간 통신이 발생
  • 조인에 사용한 특정 키나 키 집합을 어떤 노드가 가졌는지에 따라 해당 노드와 데이터를 공유
  • 네트워크는 복잡해지고 많은 자원을 공유(데이터가 잘 나뉘어있찌 않으면 더 심해짐)
  • 큰 테이블의 데이터를 다른 큰테이블의 데이터와 조인하는 과정을 잘 나타냄

브로드 캐스트 조인(큰테이블과 작은테이블 조인 good)

반응형