Hive 学习总结
Posted 怪兽宇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive 学习总结相关的知识,希望对你有一定的参考价值。
什么是 Hive
1. Hive 是一种建立在 Hadoop 文件系统上的数据仓库架构, 并对存储的数据进行分析和管理,可以将 SQL 语句转换为 MapReduce 任务进行运行,这样就使得数据开发和分析人员很方便的使用 SQL 来完成海量数据的统计和分析。
2. Hive 擅长的是非实时的、离线的、对响应及时性要求不高的海量数据批量计算,统计分析。
3. Hive 不适用于在线交易处理
Hive 的常见查询语句
Hive 中的 SELECT 基础语法和标准 SQL 语法基本一致,支持 WHERE、DISTINCT、GROUP BY、ORDER BY、HAVING、LIMIT、子查询等
1. Hive 脚本如何注释
可以用 - - 开头的字符串来表示注释, 也可以将需要注释的 sql 选中, 然后用 ctrl + ? 快捷键来进行注释。
2. 切换数据库
use android;
3. 查看表
查看当前使用的数据库中有哪些表
show tables;
查看非当前使用的数据库中有哪些表
show tables in myhive;
查看数据库中以 android 开头的表
use android;
show tables like 'android*'
查看表的详细信息
desc formatted android
4. select…from 语句
基本查询
# 查询 employee 表中的 name 和 salary。
select name, salary from employee;
加入表中一列含有多个元素, 我们可以只查找此列的第一个元素
select name, subord[0] from employees;
使用键值进行索引
select name, deductions["state taxes"] from employees;
# 可以使用 "点" 符号, 类似:表的别名 . 列名 这样的用法
select name, address.city from employees;
使用列值进行计算
select upper(name), salary, deductions["Federal Taxes"],
rount(salary * (1 - salary, deductions["Federal Taxes"])) from employees;
# ZHANGYU 100000.0 0.2 80000
使用正则表达式
# 选出所有列名以 price 作为前缀的列
select 'price.*' from stocks;
常用的关系运算
等值比较: =
等值比较:<=>
不等值比较: <>和!=
小于比较: <
小于等于比较: <=
大于比较: >
大于等于比较: >=
区间比较
空值判断: IS NULL
非空判断: IS NOT NULL
LIKE比较: LIKE
JAVA的LIKE操作: RLIKE
REGEXP操作: REGEXP
数学运算
加法操作: +
减法操作: –
乘法操作: *
除法操作: /
取余操作: %
与操作: &
或操作: |
异或操作: ^
取反操作: ~
常用的聚合函数
count(*) # 个数统计函数
count(distinct col) # 统计去重之后的个数
sum(col) # 求和
sum(distinct col) #去重之后的和
avg(col) # 平均值
avg(distinct col) # 去重之后的平均值
min(col) # 最小值
max(col) # 最大值
corr(col1, col2) # 相关系数
var_pop(clo) # 方差
var_samp(col) # 样本方差
stddev_pop(col) # 标准偏差
stddev_samp(col) # 标准样本偏差
covar_pop(col1, col2) # 协方差
covar_samp(col1, col2) # 样本协方差
select count(distinct account), avg(salary) form employees;
使用别名
select count(distinct acount) as uv from employees;
使用limit语句限制返回的行数
# 只显示 10 行
select count(distinct account) as uv form employees limit 10;
嵌套 select 语句
select e.name, e.salary
from(
select upper(name)
from employees
) as e
where e.salary > 500;
case…when..then 句式
select name , salary,
case
when salary < 5000 then 'low'
when salary > = 5000 and salary < 70000 then 'middle'
else 'high'
end as bracket from employees;
5. where 条件语句
常见用法
select * from employees where country = 'us' and state = 'ca';
可以在where条件下计算
select
name , salary, deductions['first taxes'], salary * (1-deductions['first taxes'])
from
employees
where
round(salary * (1-deductions['first taxes']) ) > 70000;
# zhangyu 100000.0 0.2 80000
对上式进行优化
select
e.*
from
(
select
name , salary, deductions['first taxes'], salary * (1-deductions['first taxes'])
from
employees
) e
where
round(salary * (1-deductions['first taxes']) ) > 70000;
条件中有浮点数
# 对浮点数进行比较
select
name, salary, duductions['first taxes']
from
employees
where
duductions['first taxes'] > 0.2;
出现的结果中会有 0.2, 因为 DOUBL 和 FLOAT 类型不同
select
name, salary, duductions['first taxes']
from
employees
where
duductions['first taxes'] > cast (0.2 as float);
出现的结果中不会有 0.2
like 和 rlike
rlike 子句是 Hive 功能的一个扩展, 可以通过 Java 的正则表达式来指定匹配条件
select name, address.street
from employees where address.street rlikt '.*(beijing|shanghai).*';
# 用like
select name, address from employees
where address.street like '%beijing%' or address.street like '%shanghai%';
6. group by 语句, order by, 与 having
分类并排序
select year(ymd), avg(price_close) from stocks
where exchange = 'nasdaq' and symbol = 'aapl'
group by year(ymd)
order by year(ymd) desc;
having 子句来限制输出结果
select year(ymd), avg(price_close) from stocks
where exchange = 'nasdaq' and symbol = 'aapl'
group by year(ymd)
having avg(price_close) > 50.0 ;
# 如果没有having, 将要使用嵌套select子查询
select s2.year, s2.avg from
(
select year(ymd) as year, avg(price_close) as avg from stocks
where exchange = 'nasdaq' and symbol = 'aapl'
group by year(ymd)
) s2
where s2.avg > 50.0
7. join 语句
Hive 中 Join 的关联键必须在 ON () 中指定,不能在 Where 中指定
内连接
只有进行连接的两个表中都存在与连接标准相匹配的数据才会被保留下来。
SELECT
a.ymd, a.price_close, b.price_close
FROM
a JOIN b ON a.ymd = b.ymd
WHERE
a.symbol = 'Apple' and b.symbol = 'Ibm'
ON 子句指定了两个表间数据进行连接的条件。
对于多张表进行连接查询
SELECT
a.ymd, a.price_close, b.price_close, c.price_close
FROM
a JOIN b ON a.ymd = b.ymd
JOIN c ON a.ymd = c.ymd
WHERE
a. symbol = 'Apple' AND b.symbol = 'Ibm' AND c.symbol = 'Google'
为什么条件内不加表 b 和表 c 进行连接操作, 因为 Hive 总是按照从左到右的顺序来执行
Join 优化
Hive 会假定查询中最后一个表是最大的表, 在对每行记录进行连续操作时, 它会
尝试将其他表缓存起来,然后扫描最后那个表进行计算。 因此, 我们在查询时, 要
保证连续查询中的表的大小从左到右依次是增加的。
假如,在 a, b 两个表中,b表最小, 则 sql 需要修改为:
SELECT
a.price_close, b.price_close
FROM
b JOIN a ON b.ymd = a.ymd AND b.symbol = a.symbol
WHERE
s.symbol = 'APPLE'
使用 “标记” 来指定哪张表是大表, 不需要排序
SELECT
/*+Streamtable(a)*/ a.price_close, b.price_close
FROM
a JOIN B on a.ymd = b.ymd AND a.symbol = b.symbol
WHERE
a.symbol = 'Apple'
左外连接
SELECT
a.price_close, b.price_close
FROM
a LEFT OUTER JOIN b on a.ymd = b.ymd AND a.symbol = b.symbol
WHERE
a.symbol = 'Apple'
左边表符合 WHERE 条件的全部返回,右表不符合 ON 条件的返回 NULL
完全外链接
SELECT
a.price_close, b.price_close
FROM
a FULL OUTER JOIN b on a.ymd = b.ymd AND a.symbol = b.symbol
WHERE
a.symbol = 'Apple'
返回所有表中符合 WHERE 语句条件的所有记录
Hive 不支持右半开连接
8. 排序 ORDER BY
Order by 对查询的所有结果进行排序
可在字段加 DESC 关键字, 进行降序排序。 (默认 ASC, 升序)
SELECT
a.price_close,
FROM
a
WHERE
a.symbol = 'Apple'
GROUP BY
a.price_close
ORDER BY
A.PRICE_close DESC
LIMIT 10;
9. 子查询
Hive 中如果是从一个子查询进行 SELECT 查询,那么子查询必须设置一个别名
From 子句进行子查询
select
dt,
count(distinct account) as uv,
count(1) as pv
from
(select
dt,
count(distinct account) as uv,
count(1) as pv
from
client.android_log_view
UNION ALL
select
dt,
count(distinct account) as uv,
count(1) as pv
from
client.ios_log_view
)
group by
dt
order by
dt
Hive 0.13 开始, Where 子句也支持子查询
SELECT *
FROM A
WHERE A.a IN (SELECT foo FROM B);
SELECT A
FROM T1
WHERE EXISTS (SELECT B FROM T2 WHERE T1.X = T2.Y)
将子查询作为一个表的语法,叫做 Common Table Expression(CTE)
with a1 as
(
select
dt,
count(distinct account) as uv,
count(1) as pv
from
client.android_log_view
where
dt between '2018-07-01' and '2018-07-03'
UNION ALL
select
dt,
count(distinct account) as uv,
count(1) as pv
from
client.ios_log_view
where
dt between '2018-07-01' and '2018-07-03'
)
select
dt,
count(distinct user_account) as uv,
count(1) as pv
from
a1
limit 10
Hive Sql 的查询优化
在查询中, 避免使用 select *, 使用条件限制取需要的列
在使用 Join 进行外关联时, 将副表的过滤条件写在 where 后面,会先全表关联, 再进行过滤, 这样会耗费资源。
SELECT
a.price_close, b.price_close
FROM
b JOIN a ON b.ymd = a.ymd AND b.symbol = a.symbol
WHERE
s.symbol = 'APPLE'
正确的写法是将 where 条件卸载 on 后面
SELECT
a.price_close, b.price_close
FROM
b JOIN a ON ( b.ymd = a.ymd AND b.symbol = a.symbol and s.symbol = 'APPLE')
count(distinct ) 在数据量特别大的情况下,效率较低, 可以用先 group by 再 count 的方式进行代替
因为 count(distinct) 是按 group by 字段分组,按 distinct 字段排序
use computer_view;
select
hit_date,
count(distinct user_account) as uv
from
client_android_log_view
where
hit_date between '2018-10-01' and '2018-10-02'
group by
hit_date
可以转换成:
use computer_view;
select
hit_date,
count(user_account) as uv
from
(select
hit_date,
user_account
from
client_android_log_view
where
hit_date between '2018-10-01' and '2018-10-02'
group by
hit_date, user_account) a
group by
hit_date
子查询 不要使用 group by
SELECT
*
FROM
(
SELECT
*
FROM t1
GROUP BY c1,c2,c3
UNION ALL
SELECT
*
FROM t2
GROUP BY c1,c2,c3
)t3
GROUP BY c1,c2,c3
应该写成
SELECT
*
FROM
(
SELECT
*
FROM t1
UNION ALL
SELECT
*
FROM t2
)t3
GROUP BY c1,c2,c3
子查询内 不要使用 count(distinct), max, min
SELECT
*
FROM
(
SELECT
*
FROM t1
UNION ALL
SELECT
c1,
c2,
c3,
COUNT(DISTINCT c4)
FROM t2
GROUP BY c1,c2,c3
)t3
GROUP BY c1,c2,c3;
可以用临时表来进行优化
INSERT t4 SELECT c1,c2,c3,c4 FROM t2 GROUP BY c1,c2,c3;
SELECT
c1,
c2,
c3,
SUM(income),
SUM(uv)
FROM
(
SELECT
c1,
c2,
c3,
income,
0 AS uv
FROM t1
UNION ALL
SELECT
c1,
c2,
c3,
0 AS income,
1 AS uv
FROM t2
)t3
GROUP BY c1,c2,c3;
参考资料:
Hive 编程指南
Hive 官网
一起学 Hive
Hive 性能优化上的一些总结
可点击:阅读原文, 访问文中链接
以上是关于Hive 学习总结的主要内容,如果未能解决你的问题,请参考以下文章