하이브 테이블의 최적화

작은 테이블은 큰 테이블 가입 

키는 상대적으로 분산시켜 작은 효과적으로 메모리 오버플로 오류의 가능성을 줄일 수있는 데이터의 양 테이블의 조인 좌측에 발생되고, 또한, 작은 사이즈 맵 테이블 (1000 이하의 레코드 번호) 고급 조인 할 메모리. 지도를 완료 끝을 줄일 수 있습니다. 

하이브 새로운 버전이 작은 테이블에 큰 테이블이 JOIN 작은 테이블에 가입 큰 테이블이 최적화된다. 작은 왼쪽 테이블과 오른쪽은 큰 차이가 없다. 

예 :

큰 테이블 만들기 (1)

테이블에서 Bigtable (생성
아이디 BIGINT, 
시간 BIGINT, 
UID 문자열 
키워드 문자열, 
url_rank의 INT, 
click_num의 INT, 
CLICK_URL 문자열
) 행 형식은 '\ t'로 종료 필드를 구분;

대량의 데이터 테이블을 가져 오기

로드 데이터 로컬 INPATH '/ 옵션 / 온도 / 하이브 / : 표': 표 테이블로;

2, 작은 테이블을 생성

smalltable 테이블 (생성
아이디 BIGINT, 
시간 BIGINT, 
UID 문자열 
키워드 문자열, 
url_rank의 INT, 
click_num의 INT, 
CLICK_URL 문자열
) 행 형식은 '\ t'로 종료 필드를 구분;

작은 테이블 데이터 가져 오기

로드 데이터 로컬 INPATH '/ 옵션 / 온도 / 하이브 / smalltable'smalltable 테이블로;

조인 후 테이블을 작성합니다

관절 식 테이블 (생성
아이디 BIGINT,
시간 BIGINT,
UID 문자열
키워드 문자열,
url_rank의 INT,
click_num의 INT,
CLICK_URL 문자열
) 행 형식은 '\ t'로 종료 필드를 구분;

(기본적으로) 4, 가까운 mapjoin 기능 

세트 hive.auto.convert.join = 거짓;

5, 작은 테이블은 대형 테이블 조인

관절 식 덮어 표를 삽입
선택 b.id, b.time, b.uid, b.keyword,
b.url_rank, b.click_num, b.click_url
smalltable의 행은
: 표 B에 가입 왼쪽
b.id = s.id 일;

시간 :

총 맵리 듀스 CPU 소비 시간 : 40초 990 밀리 초

6, 큰 테이블의 구현은 작은 테이블 문을 가입 

덮어 표를 삽입 관절 식
선택 b.id, b.time, b.uid, b.keyword, b.url_rank,
b.click_num, b.click_url
: 표 B로부터는
smalltable의 가입 왼쪽
s.id = b.id 일;

시간 :

총 맵리 듀스 CPU 소비 시간 : 43초 940 밀리 초

둘째, 큰 테이블은 큰 테이블에 참여 

1 공기 여과 KEY 

너무 많은 동일한 키에 해당하는 특정 키 데이터와 해당 데이터가 동일한 감속기로 전송되기 때문에 때때로 타임 아웃에 가입, 메모리의 결과로 충분하지 않습니다. 이 시점에서 우리는 신중하게 많은 경우, 이러한 데이터에 해당하는 키 데이터가 비정상 우리는 SQL 문에서 필터링 할 필요가,이 특이한 키를 분석해야합니다. 예를 들어, 키 필드에 해당 비어 있습니다.

예 :

(1) 원래의 테이블을 만들

테이블 오라 (생성
아이디 BIGINT,
시간 BIGINT,
UID 문자열
키워드 문자열,
url_rank의 INT,
click_num의 INT,
CLICK_URL 문자열
)에 의해 종료 행 형식으로 구분 된 필드를 '\ t';

데이터 가져 오기 :

로드 데이터 테이블 오라이에 로컬 INPATH '/opt/temp/hive/SogouQ1.txt';

(2) 빈 테이블 ID를 생성 

테이블 nullidtable (생성
아이디 BIGINT,
시간 BIGINT,
UID 문자열
키워드 문자열,
url_rank의 INT,
click_num의 INT,
CLICK_URL 문자열
)에 의해 종료 행 형식으로 구분 된 필드를 '\ t';

데이터 가져 오기 :

로드 데이터 로컬 INPATH '/ 옵션 / 온도 / 하이브 / NULLID'로 테이블 nullidtable;

(3) 후 조인 테이블 작성

테이블 nullidjointable (생성
아이디 BIGINT,
시간 BIGINT,
UID 문자열
키워드 문자열,
url_rank의 INT,
click_num의 INT,
CLICK_URL 문자열
)에 의해 종료 행 형식으로 구분 된 필드를 '\ t';

(4) 필터는 빈 ID에 대한 두 개의 테이블을 조인하지 마십시오

덮어 테이블 nullidjointable 삽입
. 선택을 N *
nullidtable에서 N은
가입 왼쪽 오라이 O
에 n.id = o.id;

시간 :

총 맵리 듀스 CPU 소비 시간 : 49초 200 밀리 초

(5) 에어 필터 키

. (ID가 널이 아닌 곳에서 선택 nullidtable *) *로부터 덮어 테이블 선택 nullidjointable N 삽입 N 왼쪽 n.id = O 오라이 o.id에 가입;

시간 :

총 맵리 듀스 CPU 소비 시간 : 22초 160 밀리 초

2, 빈 키 변환 

때로는 많은 양의 데이터에 해당하는 키 블랭크, 해당 데이터가 비정상 데이터가 아니지만, 조인의 결과에 포함되어야하며,이 경우에 우리는 데이터 무작위 그 임의의 값을 할당 된 키 빈 필드를 나열 할 수 있습니다 균등 다른 감속기에 분할되지.

(1) 임의로 널 NULL 값이 분산되지

세트 mapreduce.job.reduces = 5; 

덮어 테이블 nullidjointable 삽입
. 선택을 N *
nullidtable에서 N은
가입 왼쪽 오라이 O
에 n.id = o.id;

스큐 데이터의 출현은, 일부 감속기 자원 소비는 다른 감속기보다 훨씬 크다

(2) 임의의 분포 값 널 널

관절 식 덮어 테이블 선택 N 삽입 nullidtable * N으로부터 n.id가 널이 다음 CONCAT ( '하이브', 랜드 ()) 다른 단부 n.id = o.id 때 전체 케이스 오라이 O 가입.;

,을 제거해 데이터가 왜곡, 자원 소비의로드 밸런싱 감속기를 볼 수있다 

세, MapJoin 

如果不指定 MapJoin 或者不符合 MapJoin 的条件,那么 Hive 解析器会将 Join 操作转换成 Common Join,即:在 Reduce 阶段完成 join。容易发生数据倾斜。可以用 MapJoin 把小表全部加载到内存在 map 端进行 join,避免 reducer 处理。 

1、开启 MapJoin 参数设置 

(1)设置自动选择 MapJoin 

set hive.auto.convert.join = true; 默认为 true 

(2)大表小表的阈值设置(默认 25M 一下认为是小表)

set hive.mapjoin.smalltable.filesize=25000000;

2、MapJoin 工作机制 

 

四、Group By

默认情况下,Map 阶段同一 Key 数据分发给一个 reduce,当一个 key 数据过大时就倾斜了。 并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在 Reduce 端得出最终结果。

 1、开启 Map 端聚合参数设置 

(1)是否在 Map 端进行聚合,默认为 True 

hive.map.aggr = true 

(2)在 Map 端进行聚合操作的条目数目 

hive.groupby.mapaggr.checkinterval = 100000 

(3)有数据倾斜的时候进行负载均衡(默认是 false) 

hive.groupby.skewindata = true 

当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。 

五、 Count(Distinct) 去重统计 

数据量小的时候无所谓,数据量大的情况下,由于 COUNT DISTINCT 操作需要用一个Reduce Task 来完成,这一个 Reduce 需要处理的数据量太大,就会导致整个 Job 很难完成,一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替换。

六、笛卡尔积 

尽量避免笛卡尔积,join 的时候不加 on 条件,或者无效的 on 条件,Hive 只能使用 1个 reducer 来完成笛卡尔积。 

七、行列过滤 

1、列处理

在 SELECT 中,只拿需要的列,如果有,尽量使用分区过滤,少用 SELECT *。
2、行处理

在分区剪裁中,当使用外关联时,过滤条件最好用在子查询里

(1)先关联两张表,再用 where 条件过滤 (不推荐)

 select o.id from bigtable b join ori o on o.id = b.id where o.id <= 10; 

(2)优化后,通过子查询后,再关联表 (推荐)

 select b.id from bigtable b join (select id from ori where id <= 10 ) o on b.id = o.id; 

 

 

 

 

 

 

 

 

 

 

 

发布了69 篇原创文章 · 获赞 2 · 访问量 4117

추천

출처blog.csdn.net/zuodaoyong/article/details/104235949