CREATE VIEW student_view
AS SELECT * FROM students where score>85 ;
DESC student_view;
DROP VIEW student_view;
适用于不更新的静态字段。以免总是重建索引数据。每次建立、更新数据后,都要重建索引以构建索引表
create index student_index on table student(age) as 'compact' with deferred rebuild;
show index on student;
drop index student_index on student;
create index student_index on table student(id)as 'compact' with deferred rebuild;
alter index student_index on student rebuild;
show formatted index on student;
drop index student_index on student;
create index student_index on table student(name) as 'bitmap' with deferred rebuild;
alter index student_index on student rebuild;
show formatted index on student;
drop index student_index on student;
create index student_index on table student(age) as 'compact' with deferred rebuild in table student_index_table;
drop index student_index on student;
create index student_index on table student(name) as 'compact' with deferred rebuild stored as rcfile;
drop index student_index on student;
CREATE INDEX student_index ON TABLE student (age) AS 'COMPACT' with deferred rebuild ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE;
drop index student_index on student;
CREATE INDEX student_index ON TABLE student (age) AS 'COMPACT' with deferred rebuild IDXPROPERTIES ("prop1"="value1", "prop2"="value2");
drop index student_index on student;
CREATE INDEX student_index ON TABLE student (age) AS 'COMPACT' with deferred rebuild TBLPROPERTIES ("prop3"="value3", "prop4"="value4");
-删除索引
drop index student_index on student;
由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点
任务进度长时间维持在 99% 或者 100% 的附近, 查看任务监控页面,发现只有少量(1个或者几个) reduce 子任务未完成, 因为其处理的数据量和其他的 reduce 差异过大。 单一 reduce 处理的记录数和平均记录数相差太大,通常达到3倍甚至更多,最长时间远大于平均时长
场景说明
在日志中,常会有信息丢失的问题, 比如日志中的 user_id,如果取其中的 userid 和用户表中的 userid 相关联,就会碰到数据倾斜的问题
解决方案
解决方案 1: user_id 为空的不参与关联
SELECT * FROM log a
JOIN user b
ON a.user_id IS NOT NULL
AND a.user_id = b.user_id
UNION ALL
SELECT * FROM log c WHERE c.user_id IS NULL;
解决方案 2: 赋予空值新的 key 值
SELECT * FROM log a
LEFT OUTER JOIN user b
ON CASE WHEN a.user_id IS NULL THEN CONCAT('hive',RAND())
ELSE a.user_id END = b.user_id;
总结
方法 2 比方法 1 效率更好, 不但 IO 少了,而且作业数也少了,方案 1 中, log 表读了两次, jobs 肯定是 2,而方案 2 是 1。 这个优化适合无效 id(比如-99, ‘’, null)产生的数据倾斜, 把空值的 key 变成一个字符串加上一个随机数,就能把造成数据倾斜的数据分到不同的 reduce 上解决数据倾斜的问题
场景说明
用户表中 user_id 字段为 int, log 表中 user_id 为既有 string 也有 int 的类型。当按照两个表的 user_id 进行 Join 操作的时候,默认的 hash 操作会按照 int 类型的 id 来进行分配, 这样就会导致所有的 string 类型的 id 就被分到同一个 reducer 当中
解决方案
把数字类型 id 转换成 string 类型的 id
SELECT * FROM user a
LEFT OUTER JOIN log b
ON b.user_id = CAST(a.user_id AS STRING);
解决方案
使用 MapJoin 解决小表关联大表造成的数据倾斜问题
MapJoin 概念
将其中的某个表(全量数据)分发到所有 Map 端进行 Join,从而避免了reduce,前提要求是内存足以装下该全量数据
总结
SELECT pv.pageid, u.age FROM page_view pv
JOIN user u
ON (pv.userid = u.userid);
GROUP BY
SELECT pageid, age, count(1) FROM pv_users
GROUP BY pageid, age;
虽然经过测验, Hive 1.2.1 也支持 IN 操作,但还是推荐使用 Hive 的一个高效替代方案: LEFT SEMI JOIN
Map个数的决定因素
是不是Map数越多越好?
是不是保证每个Map处理接近128M的文件块,就高枕无忧了?
针对上面的问题,我们需要采取两种方式来解决:即减少Map数和增加Map数。
总结:如果文件大于块大小,那么会拆分,如果小于块大小,则把该文件当成一个块
怎样设置Reduce的个数
Reduce的个数是不是越多越好?
什么情况下只有一个Reduce?
Join 原则: 在使用写有 Join 操作的查询语句时有一条原则,应该将条目少的表/子查询放在 Join 操作符的左边。
如果 Join 的 key 相同,不管有多少个表,都会则会合并为一个 MapReduce,而不是 ‘n’ 个。在做 OUTER JOIN 的时候也是一样
Map 端部分聚合
并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在 Reduce 端得出最终结果
MapReduce 的 combiner 组件
\hive.map.aggr = true ##是否在 Map 端进行聚合,默认为 True
hive.groupby.mapaggr.checkinterval = 100000 ##在 Map 端进行聚合操作的条目数目
文件数目过多,会给 HDFS 带来压力,并且会影响处理效率,可以通过合并 Map 和 Reduce 的结果文件来消除这样的影响
hive.merge.mapfiles = true ##是否和并 Map 输出文件,默认为 True
hive.merge.mapredfiles = false ##是否合并 Reduce 输出文件,默认为 False
hive.merge.size.per.task = 256*1000*1000 ##合并文件的大小