반응형
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)
반응형
'Data Engineering > Spark' 카테고리의 다른 글
[Spark] 스파크 집계연산 정리 1 (0) | 2023.11.22 |
---|---|
[Spark] EMR Spark 재시작 하기 (0) | 2022.03.03 |
[ Spark ] 스파크 간단 스터디 7 (0) | 2021.07.18 |
[ Spark ] 스파크 간단 스터디 6 (0) | 2021.07.18 |
[ Spark ] 스파크 간단 스터디 5 (2) | 2021.07.11 |