Hive 조인

맵리듀스 대신 하이브를 사용할 때의 장점 중 하나는 일반적으로 사용되는 연산을 매우 간단히 수행할 수 있다는 것.



내부 조인


가장 단순한 종류의 조인은 두 개의 입력 테이블에서 일치한 행을 하나의 행으로 출력하는 내부 조인 이다.

SELECT sales.*, things.*
FROM sales
JOIN things
ON (sales.id = things.id);

-- 다른 방식

SELECT *
FROM SALES, THINGS
WHERE 


  • 하이브는 동등 조인만 지원(조인 서술자는 등호(=)만 사용할 수 있다)

조인 서술자 AND 키워드로 분리된 일련의 표현식을 사용하여 여러 개의 컬럼에 대한 조인을 수행할 수 있다. 또한 서브쿼리로 JOIN .. ON .. 절을 지원하므로 두 개 이상의 테이블도 조인할 수 있다. 하이브는 조인을 수행할 때 필요한 맵리듀스 잡의 수를 지능적을 최소화한다.


하나의 조인은 맵리듀스 잡 하나로 구현되지만, 조인 조건에 같은 컬럼이 사용되는 여러 개의 조인은 각 조인당 하나 이하의 맵리듀스 잡이 수행될 수 있다. 쿼리 앞에 EXPLAIN 키워드를 추가하면 특정 쿼리에 얼마나 많은 맵리듀스 잡이 사용되는지 확인할 수 있다.


EXPLAIN
SELECT *
FROM SALES A, THINGS B
WHERE A.ID = B.ID;


쿼리의 실행 계획에 상세한 내용, 하이브가 실행할 각 단계의 의존성 그래프인 추상 구문 트리, 각 단계에 대한 정보등을 알 수 있다. 여기서 각 단계는 하나의 맵리듀스 잡 또는 파일 이동과 같은 조작이다. 자세한 내용은 EXPLAIN EXTENDED 추가하여 실행해보면 확인할 수 있다.



외부 조인


-- LEFT
SELECT *
FROM SALES A 
LEFT OUTER JOIN THINGS B
ON (A.ID = B.ID)

-- RIGHT
SELECT *
FROM SALES A
RIGHT OUTER JOIN THINGSB
ON (A.ID = B.ID)

-- FULL
SELECT *
FROM SALES A
FULL OUTER JOIN THINGS B
ON (A.ID = B.ID)



세미 조인


SELECT *
FROM THINGS
WHERE THINGS.ID IN (SELECT ID FROM SALES);
SELECT *
FROM THINGS 
LEFT SEMI JOIN SALES
ON (SALES.ID = THINGS.ID);



맵 조인


SELECT *
FROM SALES
JOIN THINGS
ON (SALES.ID = THINGS.ID);

특정 테이블의 내용이 메모리에 모두 들어갈 수 있을 정도로 작으면 하이브는 각 매퍼에서 조인을 수행할 수 있도록 모든 데이터를 메모리에 로드한다. 이러한 방식을 맵 조인이라고 한다.


해당 쿼리를 실행하는 잡은 리듀서가 필요하지 않고 RIGHT JOIN이나 FULL OUTER JOIN에는 제대로 작동하지 않는다. 일치의 부재는 전체 입력을 대상으로 집게(리듀스)를 수행하는 과정에서만 탐지할 수 있기 때문이다.


맵 조인은 버킷 테이블을 활용할 수 있는 장점이 있다. 왼쪽 테이블의 버킷을 처리하는 매퍼는 조인을 수행할 때 오른쪽 테이블의 관련 버킷만 불러오면 된다. 조인 본문은 앞에서 본 인메모리 예제와 같다. 맵 조인을 사용하기 위해서는 다음과 같이 최적화 설정을 미리 활성화시켜 두어야 한다.

SET hive.optimize.bucketmapjoin=true;