Hive作为一种建立在Hadoop上的数据仓库,是一种能够分析、查询和存储在Hadoop中的大规模数据机制。Hive定义了简单的类SQL的查询语言,称为HQL,便于当下熟悉SQL语言的用户查询数据。
- Hive查询语言相关
1. JOIN
Hive支持两个表间以及两个以上表间的JOIN操作。Hive能够支持的JOIN操作包括:equality joins(不支持非等价连接的原因是因为这样的condition很难表达为Map/Reduce的job), outer joins,以及left semi joins。
SELECT a.* FROM a JOIN b ON (a.id = b.id)
以下查询语句Hive不支持
SELECT a.* FROM a JOIN b ON (a.id <> b.id)
除此之外,为了达到最好的性能,最好将大表放在JOIN的右边。2. AGGREGATIONS
例如,为了计算不同性别各自的用户人数,我们使用如下Query:
SELECT pv_users.gender, count (DISTINCT pv_users.userid)
FROM pv_users
GROUP BY pv_users.gender;
在Hive中,支持同时又多个AGGREGATION,但是,在多个AGGREGATION存在的情况下,DISTINCT只能对同一个COLUMN进行限定,否则尽可能用于一个COLUMN例如,
SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(*), sum(DISTINCT pv_users.userid)
FROM pv_users
GROUP BY pv_users.gender;
然而,下面的query是不允许的:
SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(DISTINCT pv_users.ip)
FROM pv_users
GROUP BY pv_users.gender;
3. UNION ALL
Hive支持UNION ALL操作。
- Hive性能相关
在使用Hive对big data进行查询操作时,效率很低,为了提升Hive在Big Data中的查询效率,此文提出了一下方法
① 我们来一起围观下Hive的Select操作。默认情况下,Hive的Select Query会scan整个待查询Table,在这里,为了能够避免每次Select都scan整个Table,推荐使用PARTITIONED BY语句:在WHERE语句中指定partition 。
SELECT page_views.*
FROM page_views
WHERE page_views.date >= '2012-08-01' AND page_views.date <= '2012-08-21'
如果是JOIN操作,则在ON语句中指定Partition。
SELECT page_views.*
FROM page_views JOIN dim_users
ON (page_views.user_id = dim_users.id AND page_views.date >= '2012-08-01' AND page_views.date <= '2012-08-21')
选项:hive.optimize.pruner = true 默认为真。
② 列裁剪
在查询数据的时候,只查询需要用到的列。
SELECT c1 from table where c2>c1
假如table中有(c1,c2,c3,c4)四列,则c3,c4会被忽略,只读c1,c2。
选项:hive.optimize.cp = true 默认为真
③ Hive参数设置
a. set mapred.reduce.taskt = ? ——设置MapReduce中reduce的数目
b. 修改Partitioner分区
c. 把表或分区组织成bucket:连接两个在相同列上划分了bucket的表,可以用map-side join高效的实现。
CLUSTERED BY字句来指定划分bucket所用的列和要划分bucket的个数。
CREATE TABLE user(id int, name String) CLUSTERED BY (id) INTO 3 BUCKETS;
④ JOIN
使用JOIN操作的查询语句,遵守原则: 应该将行数少的表/子查询放在JOIN操作符的左边。理由:JOIN操作的Reduce阶段,位于JOIN操作符左边的表的内容会被加载进内存,将行数少的表放在左边,可以有效减少out of memory错误的几率。
⑤ Map Join
当需要查询的数据在Map阶段就能访问到时,JOIN操作在Map阶段完成,不再需要Reduce。
⑥ 合并小文件
文件数目过多,会对HDFS施加压力,同样会影响Hive的处理效率。具体来说,可以通过合并Map和Reduce的结果文件来消除这些:
hive.merge.mapfiles = true, 是否合并Map输出文件,默认为True
hive.merge.mapredfiles = false 是否合并Reduce输出文件,默认为false
hive.merge.size.per.task = 512*1000*1000 合并文件大小