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;