【Python大数据笔记_day09_hive函数和调优】

hive函数

函数分类标准[重点]

原生分类标准:  内置函数 和 用户定义函数(UDF,UDAF,UDTF)
​
分类标准扩大化:  本来,UDF 、UDAF、UDTF这3个标准是针对用户自定义函数分类的; 但是,现在可以将这个分类标准扩大到hive中所有的函数,包括内置函数和自定义函数;
​
目前hive三大标准
UDF:(User-Defined-Function)普通函数:  特点是一进一出(输入一行数据输出一行数据)        举例: split
UDAF:(User-Defined Aggregation Function)聚合函数: 特点是多进一出(输入多行输出一行)   举例: count sum max  min  avg
UDTF:(User-Defined Table-Generating Functions)表生成函数:  特点是一进多出(输入一行输出多行)   举例: explode
​
查询所有hive函数名称:  show functions;
查看某函数使用帮助文档: desc function [extended] 函数名;         注意: 加上extended关键字能查看详细信息示例
-- 查看所有函数
show functions;
​
-- 分类标准扩大化
-- UDF: 普通函数 特点: 一进一出  举例: split()
-- 查看官方示例
describe function extended split;
-- 演示官方示例
SELECT split('oneAtwoBthreeCfour', '[ABC]'); -- ["one","two","three","four"]
​
-- UDAF: 聚合函数 特点: 多进一出 举例: sum() count() avg() max()  min()
-- 查看官方示例
describe function extended count;
/*
count(*): 不忽略null值统计个数
count(字段名): 忽略null值统计个数
count(常量): 举例 : count(1)  count(2)  ...
count(distinct 字段名): 忽略null值并且去重统计个数
*/
​
-- UDTF: 表生成函数 特点: 一进多哦出 举例: explode()
-- 查看官方示例
describe function extended explode;
/*
将数组a的元素分成多行,或将映射的元素分成多行和多列
数组: array[元素1,元素2,元素3...]   array(10,20,30)能够构造出数组[10,20,30]
映射: map{k1:v1,k2:v2...}  map('a',10,'b',20,'c',30)构造出映射{'a':10,'b':20,'c':30}
*/
-- 演示炸裂函数
select explode(array(10,20,30));
select explode(map('a',10,'b',20,'c',30));

复杂类型函数

hive复杂类型:   array  struct  map
​
array类型: 又叫数组类型,存储同类型的单数据的集合
     取值: 字段名[索引]   注意: 索引从0开始
     获取长度的函数: size(字段名)       常用
     判断是否包含某个数据的函数: array_contains(字段名,某数据)   常用
     对数组进行排序的函数: sort_array(数组)
​
struct类型: 又叫结构类型,可以存储不同类型单数据的集合
     取值: 字段名.子字段名n
    
map类型: 又叫映射类型,存储键值对数据的映射(根据key找value)
    取值: 字段名[key]
    获取长度的函数: size(字段名)        常用       
    获取所有key的函数: map_keys()            常用 
    获取所有value的函数: map_values()        常用 
-- 演示集合函数
select array('binzi','666','888');
select size(array('binzi','666','888'));
select array_contains(array('binzi','666','888'),'binzi');
select sort_array(array(3,1,5,2,4)); -- [1,2,3,4,5]
​
​
select map('a',1,'b',2,'c',3);
select size(map('a',1,'b',2,'c',3));
select map_keys(map('a',1,'b',2,'c',3));-- ["a","b","c"]
select map_values(map('a',1,'b',2,'c',3));-- [1,2,3]

字符串函数

字符串常见的函数:
concat: 字符串紧凑拼接到一起生成新字符串
concat_ws: 字符串用指定分隔符拼接到一起生成新字符串        常用 
length: 获取字符串长度             常用 
lower: 把字符串中的字母全部变成小写
upper: 把字符串中的字母全部变成大写
trim: 把字符串两端的空白去除         常用 
​
拓展字符串函数
substr: 截取字符串         常用 
replace: 替换字符串        常用 
regexp_replace: 正则替换字符串
parse_url: 解析url(统一资源定位符)  组成: 协议/主机地址:端口号/资源路径?查询参数
get_json_object: 获取json对象解析对应数据
-- 1.字符串相关函数
-- 演示字符串常见的函数
-- concat: 字符串紧凑拼接到一起生成新字符串
select concat('binzi', '666', '888'); -- 'binzi666888'
-- concat_ws: 字符串用指定分隔符拼接到一起生成新字符串
select concat_ws('-', 'binzi', '666', '888'); -- 'binzi-666-888'
-- length: 获取字符串长度
select length('binzi-666'); -- 9
-- lower: 把字符串中的字母全部变成小写
select lower('BINZI-666'); -- 'binzi-666'
-- upper: 把字符串中的字母全部变成大写
select upper('binzi-666'); -- 'BINZI-666'
-- trim: 把字符串两端的空白去除
select '   binzi 666  '; -- '   binzi 666   '
select trim('   binzi 666  ');-- 'binzi 666'
​
​
​
​
-- substr(字符串,开始索引,截取长度): 截取字符串,截取长度如果不写默认到结尾
-- substring(字符串,开始索引,截取长度): 截取字符串
-- 注意: 正索引从1开始正着数  负索引从-1开始倒着数
select substr('binzi666',1,2); -- 'bi'
select substr('binzi666',1); -- -- 'binzi666'
select substr('binzi666',-4);--'i666'
​
-- 已知'2023-05-21'要求分别截取年月日
select substr('2023-05-21',1,4); -- 结果2023
select substr('2023-05-21',1,7); -- 结果2023-05
select substr('2023-05-21',6,2); -- 结果05
select substr('2023-05-21',-2,2); -- 结果21
-- current_date经常用于截取日期中的年月
select `current_date`();
select substr(`current_date`(),1,7);
​
​
​
​
-- replace(大字符串,敏感词,替换后的内容):替换字符串
select replace('你TMD哦','TMD','挺萌的');
select replace('binzi-666', '666', 'num');
​
--正则表达式替换函数:regexp_replace(str, regexp, rep)
select regexp_replace('binzi-666', '\\d+', 'num');
--正则表达式解析函数:regexp_extract(str, regexp, idx)
-- 正则中()代表分组,自动从1开始生成编号,提取正则匹配到的指定组内容
select regexp_extract('binzi-666-888', '(\\d+)-(\\d+)', 1);
select regexp_extract('binzi-666-888', '(\\d+)-(\\d+)', 2);
​
​
--URL解析函数:parse_url 注意要想一次解析出多个 可以使用parse_url_tuple这个UDTF函数
-- URL: 统一资源定位符 也就是咱们常说的网址   组成: 协议/主机地址:端口号/资源路径?查询参数
select parse_url('http://www.itcast.cn/path/binzi.html?user=binzi&pwd=123', 'HOST'); -- www.itcast.cn
select parse_url('http://www.itcast.cn/path/binzi.html?user=binzi&pwd=123', 'PATH'); -- /path/binzi.html
select parse_url('http://www.itcast.cn/path/binzi.html?user=binzi&pwd=123', 'QUERY'); -- user=binzi&pwd=123
select parse_url('http://www.itcast.cn/path/binzi.html?user=binzi&pwd=123', 'QUERY', 'user'); -- binzi
select parse_url('http://www.itcast.cn/path/binzi.html?user=binzi&pwd=123', 'QUERY', 'pwd'); -- 123
​
-- json解析函数:get_json_object(json_txt, path), 细节: 整个json字符串用单引号'包裹, json字符串中的键, 值用双引号"包裹.
-- json字符串的格式: {键:值, 键: 值}
-- json数组的格式: [{键:值, 键: 值}, {键:值, 键: 值}, {键:值, 键: 值}]      -- 索引从 0 开始.
select get_json_object('{"name":"杨过", "age":"18"}', '$.name');      -- 杨过, $表示json对象
select get_json_object('[{"name":"杨过", "age":"18"}, {"name":"小龙女", "age":"26"}]', '$.[0]'); -- {"name":"杨过", "age":"18"}
select get_json_object('[{"name":"杨过", "age":"18"}, {"name":"小龙女", "age":"26"}]', '$.[1].name'); -- 小龙女,   $表示json对象

日期时间函数

current_timestamp: 获取时间原点到现在的秒/毫秒,底层自动转换方便查看的日期格式        常用 
to_date: 字符串格式时间戳转日期(年月日)
current_date: 获取当前日期(年月日)        常用
​
year: 获取指定日期时间中的年        常用 
month:获取指定日期时间中的月        常用 
day:获取指定日期时间中的日          常用 
hour:获取指定日期时间中的时
minute:获取指定日期时间中的分
second:获取指定日期时间中的秒
​
dayofmonth: 获取指定日期时间中的月中第几天
dayofweek:获取指定日期时间中的周中第几天
quarter:获取指定日期时间中的所属季度
weekofyear:获取指定日期时间中的年中第几周
​
datediff: 获取两个指定时间的差值        常用 
date_add: 在指定日期时间上加几天        常用 
date_sub: 在指定日期时间上减几天
​
unix_timestamp: 获取unix时间戳(时间原点到现在的秒/毫秒)    注意: 可以使用yyyyMMdd HH:mm:ss进行格式化转换
from_unixtime:  把unix时间戳转换为日期格式的时间          注意: 如果传入的参数是0,获取的是时间原点1970-01-01 00:00:00
-- 2.日期时间函数
-- 获取当前时间戳(时间原点到现在的秒/毫秒)
select unix_timestamp(); -- 10位的数字代表多少秒
select current_timestamp(); -- 自动转换 年月日时分秒格式
-- 获取当前日期
select current_date();
-- 字符串格式时间戳转日期
select to_date('2023-05-21 11:19:31.222000000');
select to_date(current_timestamp());
-- 依次获取年月日时分秒
select year('2023-05-21 11:19:31.222000000'); -- 2023
select month('2023-05-21 11:19:31.222000000'); -- 5
select day('2023-05-21 11:19:31.222000000'); -- 21
​
select hour('2023-05-21 11:19:31.222000000'); -- 11
select minute('2023-05-21 11:19:31.222000000'); -- 19
select second('2023-05-21 11:19:31.222000000'); -- 31
-- 依次获取月中第几天,周中第几天,季度,年中第几周
select dayofmonth('2023-05-21 11:19:31.222000000'); -- 21
select dayofweek('2023-05-21 11:19:31.222000000'); -- 1
select quarter('2023-05-21 11:19:31.222000000'); -- 2
select weekofyear('2023-05-21 11:19:31.222000000'); -- 20
​
-- 计算时间差
select datediff(`current_date`(),'2023-11-03'); -- 12
​
-- 获取明天的日期
select date_add(current_timestamp(),1);
select date_sub(current_timestamp(),-1);
-- 获取昨天的日期
select date_sub(current_timestamp(),1);
select date_add(current_timestamp(),-1);
​
​
-- 拓展
--获取当前UNIX时间戳函数: unix_timestamp
select unix_timestamp();
​
--字符串日期转UNIX时间戳函数: unix_timestamp
select unix_timestamp("2023-5-21 11:38:56"); -- 1684669136
​
--指定格式日期转UNIX时间戳函数: unix_timestamp
select unix_timestamp('2023-05-21 11:38:56','yyyy-MM-dd HH:mm:ss'); --1684669136
​
--UNIX时间戳转日期函数: from_unixtime
select from_unixtime(1684669136); -- 2023-05-21 11:38:56
-- 获取时间原点日期
select from_unixtime(0); -- 1970-01-01 00:00:00

数学函数

round: 指定小数保留位数    常用
rand: 生成0-1的随机数
pi: 生成π结果
ceil: 向上取整
floor: 向下取整
-- 演示数学函数
-- 随机数
select rand();
-- 应用解决数据倾斜问题,可以把之前大量相同的值后面拼接随机数
select concat('男',rand());
select concat('男',rand());
​
-- 获取π值
select '3.1415926';
select pi();
-- 四舍五入设置保留位数
select round(pi(),4);
-- 向上取整
select ceil(pi());
-- 向下取整
select floor(pi());

条件函数[练习]

if(参数1,参数2,参数3): 如果参数1结果为true,就执行参数2内容,否则执行参数3的内容
case...when.then...end: 条件判断类似于编程语言中的if..else if ...else...     常用
​
​
isnull(数据) : 为空null: true 不为空:false
​
isnotnull(数据): 不为空: true 为空null:false
​
nvl(数据,参数2): 如果数据不为空打印数据,为空null打印第二个参数        常用 
​
coalesce(参数1,参数2...): 从左到右依次查找,返回第一个不是null的值,如果找到最后都是null,就返回null    常用
-- 演示条件函数
-- if(条件判断,true的时候执行此处,false的时候执行此处)
select if(10 > 5, '真', '假'); -- 真
select if(10 < 5, '真', '假');
--条件转换函数格式1: CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END
select
       case 7
           when 1 then '周一上班'
           when 2 then '周二上班'
           when 3 then '周三上班'
           when 4 then '周四上班'
           when 5 then '周五上班'
           when 6 then '周六休息'
           when 7 then '周日休息'
           else '老弟啊,你是外星人吗?'
       end;
​
-- 条件转换函数格式2:CASE  WHEN a==b THEN a==c [WHEN a==d THEN a==e]* [ELSE f] END
select
       case
           when 7==1 then '周一上班'
           when 7==2 then '周二上班'
           when 7==3 then '周三上班'
           when 7==4 then '周四上班'
           when 7==5 then '周五上班'
           when 7==6 then '周六休息'
           when 7==7 then '周日休息'
           else '老弟啊,你是外星人吗?'
       end;
​
​
-- 演示null相关函数
-- isnull(数据) 为空: true 不为空:false
select isnull(null); -- true
-- isnotnull(数据) 不为空: true 为空:false
select isnotnull('斌子'); -- true
-- nvl(数据,前面的数据是null的时候执行此处): 如果数据不为空打印数据,为空打印第二个参数
select nvl('binzi','666');
select nvl(null,'666');
-- coalesce(v1,v2...): 从左到右依次查找,返回第一个不是null的值,如果找到最后都是null,就返回null
select COALESCE(null,11,22,33);-- 11
select COALESCE(null,null,22,33);--22
select COALESCE(null,null,null,33);--33
select COALESCE(null,null,null,0);--0
select COALESCE(null,null,null,null);--null

类型转换函数

类型转换: cast(数据 as 要转换的类型)        常用 
-- 演示类型转换函数
​
-- cast: 主要用于类型转换 注意: 转换失败返回null
select cast(3.14 as int); -- 3
select cast(3.14 as string) ; -- '3.14'
select cast('3.14' as float); -- 3.14
select cast('3.14' as int); -- 3
select cast('binzi' as int); -- null
​
-- -- 注意: 很多时候底层都默认做了自动转换
select '3'+3; -- 6
​
​
-- 实际应用场景:concat_ws要求被连接的必须是字符串,如果直接用666就报错
select concat_ws('_','binzi',666,'888'); --此行报错,因为concat_ws只能拼接字符串类型
select concat_ws('_','binzi',cast(666 as string),'888'); -- binzi_666_888

数据脱敏函数

-- 演示数据脱敏函数[了解]
-- mask_hash:  返回指定字符串的hash编码
select mask_hash('binzi');
​
​
-- 拓展
--将查询回的数据,大写字母转换为X,小写字母转换为x,数字转换为n。
select mask("abc123DEF"); -- xxxnnnXXX
--自定义替换的字母: 依次为大写小写数字
select mask("abc123DEF",'大','小','数');
select mask("abc123DEF",'/','.','%');
​
--mask_first_n(string str[, int n]
--对前n个进行脱敏替换 大写字母转换为X,小写字母转换为x,数字转换为n。
select mask_first_n("abc123DEF",6);
​
--mask_last_n(string str[, int n])
--对后n个进行脱敏替换 大写字母转换为X,小写字母转换为x,数字转换为n。
select mask_last_n("abc123DEF",6);
​
--mask_show_first_n(string str[, int n])
--除了前n个字符,其余进行掩码处理
select mask_show_first_n("abc123DEF",6);
​
--mask_show_last_n(string str[, int n])
select mask_show_last_n("abc123DEF",6);

其他函数

-- 演示其他函数
--取哈希值函数:hash
select hash("binzi"); -- 93742710
​
--MD5加密: md5(string/binary)
select md5("binzi"); -- 32位   072853027b387fcf891a610137f8dc1b
select length('072853027b387fcf891a610137f8dc1b');
​
​
--SHA-1加密: sha1(string/binary)
select sha1("binzi"); -- 40位 66368c80ca9125f9a8a945aaf1e1ec3f8b21f7f9
select length('66368c80ca9125f9a8a945aaf1e1ec3f8b21f7f9');
​
--SHA-2家族算法加密:sha2(string/binary, int)  (SHA-224, SHA-256, SHA-384, SHA-512)
select sha2("binzi",224);
select sha2("binzi",512);
​
--crc32加密:
select crc32("binzi"); -- 3221865747
​
​
-- 当前环境相关的
select current_user(),logged_in_user(),current_database(),version();

炸裂函数实战[练习]

把一个容器的多个数据炸裂出单独展示:  explode(容器)
​
炸裂函数配合侧视图使用如下
格式:select 原表别名.字段名,侧视图名.字段名 from 原表 原表别名 lateral view explode(要炸开的字段) 侧视图名 as 字段名 ;
-- UDTF: 一进多出
select explode(array('binzi', '666', '888'));
select explode(map('a', 1, 'b', 2, 'c', 3));

实战

-- 将NBA总冠军球队数据使用explode进行拆分,并且根据夺冠年份进行倒序排序。
--step1:建表
create table the_nba_championship(
           team_name string,
           champion_year array<string>
) row format delimited
fields terminated by ','
collection items terminated by '|';
​
--step2:加载数据文件到表中  先上传到hdfs/source目录
load data  inpath '/source/The_NBA_Championship.txt' into table the_nba_championship;
​
--step3:验证
select * from the_nba_championship;
​
​
-- 只查询冠军年份,降序排序
select explode(champion_year) as year from the_nba_championship ;
​
-- 配合侧视图完成需求
with tmp as(
    select  a.team_name,b.year
    from the_nba_championship a
    lateral view explode(champion_year) b as year
    )
select * from tmp order by year desc;

堆内存错误

报错

Error while processing statement: FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. Java heap space

解决方案:

方式1: 找到hive-env.sh,添加以下内容

    export HADOOP_HEAPSIZE=2048

方式2: 找到hive-site.xml添加以下内容

  <!-- hive堆内存-->
    <property>
        <name>hive.heapsize</name>
        <value>2048</value>
    </property>

高频面试题[练习]

行转列

collect_set(字段名): 把多个数据收集到一起,默认去重
collect_list(字段名): 把多个数据收集到一起,默认不去重
把多个子串用指定分隔符拼接成一个大字符串: concat_ws(分隔符,多个数据...)      注意: 如果拼接数据不是字符串可以使用cast转换
示例:
-- 数据准备
--建表
create table row2col2(
                         col1 string,
                         col2 string,
                         col3 int
)row format delimited fields terminated by '\t';
​
--加载数据到表中
load data inpath '/source/r2c2.txt' into table row2col2;
-- 验证数据
select * from row2col2;
/*
需求1: 把原表数据变成以下格式
a b [1,2,3]
c d [4,5,6]
*/
select
    col1,
    col2,
    collect_list(col3)
from
    row2col2
group by
    col1, col2;
​
/*
需求2: 把原表数据变成以下格式
a b '1-2-3'
c d '4-5-6'
*/
select
    col1,
    col2,
    concat_ws('-',collect_list(cast(col3 as string)))
from
    row2col2
group by
    col1, col2;

列转行

知识点
把字符串按照指定分隔符切割: split(字符串,分隔符)
​
炸裂函数配合侧视图使用格式: select 原表别名.字段名,侧视图名.字段名 from 原表 原表别名 lateral view explode(要炸开的字段) 侧视图名 as 字段名 ;
需求

示例
-- 列转行
--创建表
create table col2row2(
                         col1 string,
                         col2 string,
                         col3 string
)row format delimited fields terminated by '\t';
​
--加载数据
load data  inpath '/source/c2r2.txt' into table col2row2;
-- 验证数据
select * from col2row2;
​
​
-- 单列数据先切割再炸开
select split(col3,',') from col2row2;
select explode(split(col3,',')) from col2row2;
​
-- 再去完成需求,列转行生成最后完整表
select col1,col2,tmp.col3
from col2row2
 lateral view explode(split(col3,',')) tmp as col3;

JSON文件处理

get_json_object: 获取json对象解析对应数据  一次只能提取一个字段
​
json_tuple: 直接获取json对应数据  这是一个UDTF函数 可以一次解析提取多个字段
​
注意: 因为json_tuple是UDTF函数,所以也可以配合侧视图使用
-- 演示json解析
-- 需求: 把json解析后的数据保存成一个新表
--创建表
create table tb_json_test1 (
    json string
);
​
--加载数据
load data  inpath '/source/device.json' into table tb_json_test1;
-- 查看数据
select * from tb_json_test1;
​
-- 方式1: 逐个(字段)处理, get_json_object UDF函数 最大弊端是一次只能解析提取一个字段
-- get_json_object UDF函数 最大弊端是一次只能解析提取一个字段
create table device1 as
select
    --获取设备名称
    get_json_object(json,"$.device") as device,
    --获取设备类型
    get_json_object(json,"$.deviceType") as deviceType,
    --获取设备信号强度
    get_json_object(json,"$.signal") as signal,
    --获取时间
    get_json_object(json,"$.time") as stime
from tb_json_test1;
​
​
-- 方式2: 逐条处理. json_tuple 这是一个UDTF函数 可以一次解析提取多个字段
--json_tuple 这是一个UDTF函数 可以一次解析提取多个字段
--单独使用 解析所有字段
create table device2 as
select
    json_tuple(json,"device","deviceType","signal","time") as (device,deviceType,signal,stime)
from tb_json_test1;
​
--搭配侧视图使用(本次了解)
select
    device,deviceType,signal,stime
from tb_json_test1
         lateral view json_tuple(json,"device","deviceType","signal","time") b
         as device,deviceType,signal,stime;
​
​
-- 方式3: 在建表时候, 直接处理json, row format SerDe '能处理Json的SerDe类'
--建表的时候直接使用JsonSerDe解析
create table tb_json_test2 (
                               device string,
                               deviceType string,
                               signal double,
                               `time` string
)ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' STORED AS TEXTFILE;
-- 加载数据
load data  inpath '/source/device.json' into table tb_json_test2;
-- 查看
select * from tb_json_test2;

开窗函数

基础使用[回顾]

基础知识点[重点]

开窗函数格式:  select ... 开窗函数 over(partition by 分组字段名 order by 排序字段名 asc|desc) ... from 表名;
​
聚合开窗函数: 原来学的聚合函数(max,min,sum,count,avg)配合over()使用的时候,这些聚合函数也可以叫开窗函数
​
排序开窗函数: row_number  dense_rank  rank
            row_number: 巧记: 1234   特点: 唯一且连续
            dense_rank: 巧记: 1223   特点: 并列且连续
               rank   : 巧记: 1224   特点: 并列不连续
-- 开窗函数: hive和mysql8都能使用
-- 开窗函数本质在表后新增了一列
-- 聚合开窗函数: max min sum avg count
-- 聚合函数配合over()使用,也可以叫开窗函数
select col1,
       max(col3) over()
from row2col2;
​
​
-- 排序开窗函数: row_number  rank  dense_rank
-- 排序函数必须配合over(order by 排序字段 asc|desc)
/*
row_number: 巧记: 1234   特点: 唯一且连续
dense_rank: 巧记: 1223   特点: 并列且连续
   rank   : 巧记: 1224   特点: 并列不连续
*/
select *,
       row_number() over (order by signal desc),
       dense_rank() over (order by signal desc),
       rank() over (order by signal desc)
from device1;
​
-- 开窗函数分组
-- 注意不能用group by ,需要使用partition by,可以理解成partition by是group by的子句
-- 演示排序函数和分组配合使用: 先分组再组内排序
select *,
       row_number() over (partition by deviceType order by signal desc),
       dense_rank() over (partition by deviceType order by signal desc),
       rank() over (partition by deviceType order by signal desc)
from device1;
-- 演示聚合函数和分组配合使用
select *,
       max(signal) over(partition by deviceType)
from device1;
​
​
-- 演示聚合函数同时和分组以及排序关键字配合使用
--需求:求出每个用户截止到当天,累积的总pv数
---建表并且加载数据
create table website_pv_info(
   cookieid string,
   createtime string,   --day
   pv int
) row format delimited
fields terminated by ',';
-- 建表
create table website_url_info (
    cookieid string,
    createtime string,  --访问时间
    url string       --访问页面
) row format delimited
fields terminated by ',';
-- 加载数据  直接上传website_pv_info.txt和website_url_info.txt到hdfs中指定表路径中
-- 查询数据
select * from website_pv_info;
select * from website_url_info;
​
--需求:求出每个用户截止到当天,累积的总pv数
--sum(...) over( partition by... order by ... ),在每个分组内,连续累积求和
select cookieid, createtime,  pv,
       sum(pv) over(partition by cookieid order by createtime) as current_total_pv
from website_pv_info;

开窗函数控制范围

开窗函数控制范围: rows between
                    - unbounded: 无界限
                    - x preceding:往前x行
                    - x following:往后x行
                    - current row:当前行
       
                    - unbounded preceding :表示从前面的起点  第一行
                    - unbounded following :表示到后面的终点  最后一行         
-- 演示窗口范围的控制
/*
rows between
    - preceding:往前
    - following:往后
    - current row:当前行
    - unbounded:起点
    - unbounded preceding 表示从前面的起点  第一行
    - unbounded following:表示到后面的终点  最后一行
*/
--默认从第一行到当前行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime) as pv1
from website_pv_info;
​
--第一行到当前行 等效于rows between不写 默认就是第一行到当前行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between unbounded preceding and current row) as pv2
from website_pv_info;
​
​
--向前3行至当前行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between 3 preceding and current row) as pv4
from website_pv_info;
​
--向前3行 向后1行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between 3 preceding and 1 following) as pv5
from website_pv_info;
​
--当前行至最后一行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between current row and unbounded following) as pv6
from website_pv_info;
​
--第一行到最后一行 也就是分组内的所有行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between unbounded preceding  and unbounded following) as pv6
from website_pv_info;
​

其他开窗函数

其他开窗函数: ntile   lag和lead   first_value和last_value
​
ntile(x)功能: 将分组排序之后的数据分成指定的x个部分(x个桶)   
        注意ntile规则:尽量平均分配 ,优先满足最小(编号1)的桶,彼此最多不相差1个。
​
lag: 用于统计窗口内往上第n行值
lead:用于统计窗口内往下第n行值
​
first_value: 取分组内排序后,截止到当前行,第一个值
last_value : 取分组内排序后,截止到当前行,最后一个值
​
注意: 窗口函数结果都是单独生成一列存储对应数据
-- 演示其他函数
-- 演示ntile
--把每个分组内的数据分为3桶
SELECT
    cookieid,
    createtime,
    pv,
    ntile(3) OVER(PARTITION BY cookieid ORDER BY createtime) AS rn2
FROM website_pv_info
ORDER BY cookieid,createtime;
​
--需求:统计每个用户pv数最多的前3分之1天。
--理解:将数据根据cookieid分 根据pv倒序排序 排序之后分为3个部分 取第一部分
SELECT * from
(SELECT
     cookieid,
     createtime,
     pv,
     NTILE(3) OVER(PARTITION BY cookieid ORDER BY pv DESC) AS rn
 FROM website_pv_info) tmp where rn =1;
​
​
​
​
--lag 用于统计窗口内往上第n行值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    lag(createtime, 1) over (partition by cookieid order by createtime) la1,
    lag(createtime, 2, '2000-01-01 00:00:00') over (partition by cookieid order by createtime) la2
from website_url_info;
​
​
--lead 用于统计窗口内往下第n行值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    lead(createtime, 1) over (partition by cookieid order by createtime) la1,
    lead(createtime, 2, '2000-01-01 00:00:00') over (partition by cookieid order by createtime) la2
from website_url_info;
​
​
--FIRST_VALUE 取分组内排序后,截止到当前行,第一个值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    first_value(url) over (partition by cookieid order by createtime) fv
from website_url_info;
​
​
--LAST_VALUE  取分组内排序后,截止到当前行,最后一个值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    last_value(url) over (partition by cookieid order by createtime rows between unbounded preceding and unbounded following) fv
from website_url_info;

hive调优

hive官方配置URL: Configuration Properties - Apache Hive - Apache Software Foundation

hive命令个参数配置

hive参数配置的意义:开发hive应用调优时,不可避免地需要设定hive的参数.设定hive的参数可以调优HQL代码的执行效率,或帮助定位问题.然而实践中经常遇到的一个问题,为什么我设定的参数没有起作用?这是对hive参数配置几种方式不了解导致的!

hive参数设置范围 : 配置文件参数 >   命令行参数  >   set参数声明

hive参数设置优先级: set参数声明  >   命令行参数   >  配置文件参数

注意: 一般执行SQL需要指定的参数, 都是通过 set参数声明 方式进行配置,因为它属于当前会话的临时设置,断开后就失效了

 hive数据压缩

hive底层是运行MapReduce,所以hive支持什么压缩格式本质上取决于MapReduce.

压缩对比

在后续可能会使用GZ(GZIP), 保证压缩后的数据更小, 同时压缩和解压的速度比较OK的,

但是大部分的选择主要会选择另一种压缩方案, snappy, 此种方案可以保证在合理的压缩比下, 拥有更高的解压缩的速度

snappy | A fast compressor/decompressor On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.

 

开始压缩

 开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量. 当Hive将输出写入到表中时,输出内容同样可以进行压缩。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

-- 创建数据库
create database hive05;
-- 使用库
use hive05;


-- 开启压缩(map阶段或者reduce阶段)
--开启hive支持中间结果的压缩方案
set hive.exec.compress.intermediate; -- 查看默认
set hive.exec.compress.intermediate=true ;
--开启hive支持最终结果压缩
set hive.exec.compress.output; -- 查看默认
set hive.exec.compress.output=true;

--开启MR的map端压缩操作
set mapreduce.map.output.compress; -- 查看默认
set mapreduce.map.output.compress=true;
--设置mapper端压缩的方案
set mapreduce.map.output.compress.codec; -- 查看默认
set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

-- 开启MR的reduce端的压缩方案
set mapreduce.output.fileoutputformat.compress; -- 查看默认
set mapreduce.output.fileoutputformat.compress=true;
-- 设置reduce端压缩的方案
set mapreduce.output.fileoutputformat.compress.codec; -- 查看默认
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
--设置reduce的压缩类型
set mapreduce.output.fileoutputformat.compress.type; -- 查看默认
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

hive数据存储

行列存储原理

行存储的特点: 查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

行存储: textfile和squencefile
    优点: 每行数据连续存储              select * from 表名; 查询速度相对较快
    缺点: 每列类型不一致,空间利用率不高   select 列名 from 表名; 查询速度相对较慢
列存储: orc和parquet
    优点: 每列数据连续存储         select 列名 from 表名;  查询速度相对较快
    缺点: 因为每行数据不是连续存储  select * from 表名;查询速度相对较慢
    
注意: ORC文件格式的数据, 默认内置一种压缩算法:zlib , 在实际生产中一般会将ORC压缩算法替换为 snappy使用,格式为: STORED AS orc tblproperties ("orc.compress"="SNAPPY") 

存储压缩比

-- 存储格式应用对比
-- 演示textfile行存储格式: 18.1 m
create table log_text (
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE ; -- TEXTFILE当前默认的,可以省略

-- 查询数据
select * from log_text;



-- 演示orc列存储(默认zlib): 2.78 m
create table log_orc(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc ;-- 默认内置一种压缩算法:ZLIB

-- 加载数据(先上传数据文件到根目录)
insert into table log_orc select * from log_text;
-- 查询数据
select * from log_orc;


-- [重点orc配合snappy]
-- 演示orc列存储(指定snappy): 3.75 m
create table log_orc_snappy(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc tblproperties ("orc.compress"="SNAPPY"); -- 配合SNAPPY压缩

-- 加载数据(先上传数据文件到根目录)
insert into table log_orc_snappy select * from log_text;
-- 查询数据
select * from log_orc_snappy;

/*ORC文件格式的数据, 默认内置一种压缩算法:ZLIB , 在实际生产中一般会将ORC压缩算法替换为 snappy
格式为: STORED AS orc tblproperties ("orc.compress"="SNAPPY") */




-- 演示parquet压缩存储:13.09 m
create table log_parquet(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS PARQUET ;

-- 加载数据(先上传数据文件到根目录)
insert into table log_parquet select * from log_text;
-- 查询数据
select * from log_parquet;

 拓展dfs -du -h

-- 查看hdfs文件大小除了去页面查看,还可以通过命令
dfs -du -h '/user/hive/warehouse/hive05.db/log_text/log.data' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc_snappy/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_parquet/000000_0' ;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/152502.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis CURD操作深度解析

文章目录 简单查询操作插入、更新和删除操作selectKey元素的作用结语 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;MyBatis ✨文章内容&#xff1a; CURD操作 &#x1f9…

Alibaba微服务组件Nacos注册中心

1. 什么是 Nacos 官方&#xff1a;一个更易于构建云原生应用的动态 服务发现( Nacos Discovery ) 、 服务配置( Nacos Config ) 和服务管理平台。 集 注册中心配置中心服务管理 平台 Nacos 的关键特性包括: 服务发现和服务健康监测 动态配置服务 动态 DNS 服务 服务及其…

ps5计时计费软件安装教程,佳易王电玩店计时收费系统

ps5计时计费软件安装教程&#xff0c;佳易王电玩店计时收费系统 一、佳易王电玩PS5游戏厅计时计费软件部分功能简介&#xff1a; 1、计时计费功能 &#xff1a;开台时间和所用的时长直观显示&#xff0c;每3秒即可刷新一次时间。 2、销售商品功能 &#xff1a;商品可以绑定桌…

2023双十一爆冷收场,订单后暗藏这些电商痛点问题需要注意

打开某软件的瞬间&#xff0c;手不小心抖一下就进入了淘宝&#xff0c;而且无法第一时间准确找到关闭按钮。相信不少人都在这个双十一通过开屏广告为淘宝“贡献”至“超8亿”的访问量&#xff0c;更有网友辣评&#xff1a;“现在打开别的软件跳转淘宝的速度都比直接打开淘宝要快…

MySQL怎样处理排序⭐️如何优化需要排序的查询?

前言 在MySQL的查询中常常会用到 order by 和 group by 这两个关键字 它们的相同点是都会对字段进行排序&#xff0c;那查询语句中的排序是如何实现的呢&#xff1f; 当使用的查询语句需要进行排序时有两种处理情况&#xff1a; 当前记录本来就是有序的&#xff0c;不需要进…

折爱心教程(简单版本)

文章目录 1.折出双三角形2.向中心折叠3.形成正方形4.对折正反面相同5.向中心折6.外侧角向中心折7.顶部三角形向下折叠注意参考资料 我怎么也没有想到&#xff0c;身为混迹职场多年的老油子&#xff0c;竟然还能遇到折纸这种硬性task。 可是给的教程步骤省略太多了&#xff0c;看…

uni-app:如何配置uni.request请求的超时响应时间(全局+局部)

方法一&#xff1a;全局配置响应时间 一、进入项目的manifest.json的代码视图模块 二、写入代码 "networkTimeout": {"request": 5000 }, 表示现在request请求响应时间最多位5秒 方法二&#xff1a;局部设置响应时间 一、直接在uni.request中写入属性…

深度学习YOLOv5车辆颜色识别检测 - python opencv 计算机竞赛

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0…

最新AI创作系统ChatGPT系统运营源码/支持最新GPT-4-Turbo模型/支持DALL-E3文生图

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

高级数据结构——树状数组

树状数组&#xff08;Binary Index Tree, BIT&#xff09;&#xff0c;是一种一般用来处理单点修改和区间求和操作类型的题目的数据结构&#xff0c;时间复杂度为O(log n)。 对于普通数组来说&#xff0c;单点修改的时间复杂度是 O(1)&#xff0c;但区间求和的时间复杂度是 O(n…

【创作活动】作为程序员的那些愚蠢瞬间

作为一名程序员&#xff0c;我相信你一定遇到过这种情况&#xff1a;在写代码的时候&#xff0c;遇到了一些bug&#xff0c;在当下怎么检查都查不出问题出现在哪&#xff0c;等过几天后突然发现困扰自己的问题原来这么简单&#xff0c;突然觉得自己很蠢。这种情况在我身上也发生…

人工智能-深度学习之序列模型

想象一下有人正在看网飞&#xff08;Netflix&#xff0c;一个国外的视频网站&#xff09;上的电影。 一名忠实的用户会对每一部电影都给出评价&#xff0c; 毕竟一部好电影需要更多的支持和认可。 然而事实证明&#xff0c;事情并不那么简单。 随着时间的推移&#xff0c;人们对…

漏洞分析 | 漏洞调试的捷径:精简代码加速分析与利用

0x01前言 近期&#xff0c;Microsoft威胁情报团队曝光了DEV-0950&#xff08;Lace Tempest&#xff09;组织利用SysAid的事件。随后&#xff0c;SysAid安全团队迅速启动了应急响应&#xff0c;以应对该组织的攻击手法。然而&#xff0c;在对漏洞的分析和复现过程中&#xff0c…

使用Microsoft Dynamics AX 2012 - 1. 什么是Microsoft Dynamics AX?

Dynamics AX是Microsoft的核心业务管理解决方案&#xff0c;旨在满足中型公司和跨国组织的要求。基于 DynamicsAX基于最先进的体系结构和深度集成&#xff0c;在确保高可用性的同时&#xff0c;展现了全面的功能。 在AX 2012版中&#xff0c;Dynamics AX显示了大量新功能和增强…

Postman内置动态参数以及自定义的动态参数

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 一&#xff09;内置动态参数 {{$timestamp}} 生成当前时间的时间戳{{$randomInt}} 生成0-1000之间的随机数{{$guid}} 生成随…

⑩【MySQL】存储引擎详解, InnoDB、MyISAM、Memory。

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 存储引擎 ⑩【MySQL存储引擎】1. MySQL体系结构…

隐私协议 Secret Network 宣布使用 Octopus Network 构建的 NEAR-IBC 连接 NEAR 生态

2023年11月 NearCon2023 活动期间&#xff0c;基于 Cosmos SDK 构建的隐私协议 Secret Network&#xff0c;宣布使用 Octopus Network 开发的 NEAR-IBC&#xff0c;于2024年第一季度实现 Secret Network 与 NEAR Protocol 之间的跨链交互。 这将会是Cosmos 生态与 NEAR 之间的首…

java VR全景商城免费搭建 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

一个开源的汽修rbac后台管理系统项目,基于若依框架,实现了activiti工作流,附源码

文章目录 前言&源码项目参考图&#xff1a; e店邦O2O平台项目总结一、springboot1.1、springboot自动配置原理1.2、springboot优缺点1.3、springboot注解 二、rbac2.1、概括2.2、三个元素的理解 三、数据字典3.1、概括与作用3.2、怎么设计3.3、若依中使用字典 四、工作流—…

STM32CubeIDE报“xxx is not implemented and will always fail”解决方法

本文介绍STM32CubeIDE报“xxx is not implemented and will always fail”解决方法。 最近用STM32CubeIDE开发STM32程序时&#xff0c;编译报警告&#xff1a; warning: _close is not implemented and will always fail warning: _lseek is not implemented and will always…