热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

oraclerollup分组没有数据时为0_Hive入门数据分析基础5

六,常用优化技巧---主要内容和思路来源:开课吧学习笔记1,用groupby代替distinct去重在数据量大,重复值多时,能先使用groupby去重的,使用groupby去重后再

六, 常用优化技巧---主要内容和思路来源:开课吧学习笔记

1, 用 group by 代替 distinct 去重

在数据量大, 重复值多时, 能先使用 group by 去重的, 使用 group by 去重后再计算, 比之后再去重计算效率更高.

例如前面的例题中, 查询 2019 年购买后又退款的用户, 可以这样优化:

select a.user_name
from
(select user_name
from user_trade
where year(dt)=2019
group by user_name) a
join
(select user_name
from user_refund
where year(dt)=2019
group by user_name) b
on a.user_name=b.user_name;

2, 多维度聚合

需要对多个字段进行聚合运算, 一个字段一个字段的写 SQL 计算, 不如使用多维度聚合计算语句: grouping sets, cuberollup.

2.01, 分别查询用性别, 城市, 等级分布:

select sex, city, level,
count(user_id)
from user_info
group by sex, city, level;

上述 sql 查询出来的是同一性别, 不同城市, 不同等级的分布, 而我们需要的结果是三个字段的结果是分开的:

select sex, city, level,
count(user_id)
from user_info
group by sex, city, level
grouping sets (sex, city, level);

sexcitylevel_c3
NULLNULL133
NULLNULL226
NULLNULL330
NULLNULL444
NULLNULL530
NULLNULL632
NULLNULL735
NULLNULL834
NULLNULL930
NULLNULL1033
NULLbeijingNULL53
NULLchangchunNULL53
NULLguangzhouNULL55
NULLhangzhouNULL57
NULLshanghaiNULL61
NULLshenzhenNULL48
femaleNULLNULL177
maleNULLNULL150

a, grouping sets() 相当于将不同 group by 聚合的结果进行 union all, 可以在括号中指明聚合规则.

2.02, 查询性别分布, 以及不同性别的城市分布:

select sex, city,
count(user_id)
from user_info
group by sex, city
grouping sets (sex, (sex, city));

sexcity_c2
femaleNULL177
femalebeijing26
femalechangchun32
femaleguangzhou30
femalehangzhou30
femaleshanghai36
femaleshenzhen23
maleNULL150
malebeijing27
malechangchun21
maleguangzhou25
malehangzhou27
maleshanghai25
maleshenzhen25

城市一列为 null 的是性别分布, 其他的是每个性别的城市分布.

b, with cube将分组聚合的所有维度都进行计算:

2.03, 查询性别, 城市, 等级各种组合的用户分布情况:

-- 方法一
select sex, city, level,
count(user_id)
from user_info
group by sex, city, level
grouping sets (sex, city, level,
(sex, city), (sex, level), (city, level),
(sex, city, level));

-- 方法二
select sex, city, level,
count(user_id)
from user_info
group by sex, city, level
with cube;

方法二将所有用户数进行了统计, 方法一没有.

c, with rollup以最左侧的字段为主, 进行层级聚合, 结果是 with cube 的子集.

2.04, 查询每个月的支付金额及每年的支付金额:

-- 方法一
select a.dt,
sum(a.year_amount),
sum(a.month_amount)
from
(select substr(dt, 1, 4) dt,
sum(pay_amount) year_amount,
0 month_amount
from user_trade
where dt>'0'
group by substr(dt, 1, 4)
union all
select substr(dt, 1, 7) dt,
0 year_mount,
sum(pay_amount) month_amount
from user_trade
where dt>'0'
group by substr(dt, 1, 7)
) a
group by a.dt;

a.dt_c1_c2
201724333973.600.00
2017-010.00241755.70
2017-020.002582410.60

第一列是年的总额.

-- 方法二
select year(dt) year,
month(dt) month,
sum(pay_amount)
from user_trade
where dt>'0'
group by year(dt), month(dt)
with rollup;

yearmonth_c2
NULLNULL62348041.30
2017NULL24333973.60
20171241755.70
201722582410.60

第一列是全部的总额, 第二列是年的总额. with rollup计算了全部的总额和以 year 字段为主的两个维度 year, (year, month)的总额.

3, 转换解题思路

前面的例题, 查询 2017 和 2018 都购买的用户, 可以如下优化:

select a.user_name
from (select user_name,
count(distinct year(dt)) year_num
from user_trade
where year(dt) in (2017, 2018)
group by user_name) a
where a.year_num=2;

-- 还可再优化
select user_name,
count(distinct year(dt)) year_num
from user_trade
where year(dt) in (2017, 2018)
group by user_name
having count(distinct year(dt))=2;

4, 有 union all 查询时, 开启并发执行

开启参数设置: set hive.exec.parallel=true

查看是否设置成功: set hive.exec.parallel;

多台服务器时开启才有效.

5, 同一字段的数据展开, 或按分组归类

有用户购买的商品表 user_goods_category:

col_namedata_type
user_namestring
category_detailstring

部分数据:

Abbyclothes,food,electronics
Ailsabook,clothes,food
Albertclothes,electronics,computer

a, 同一字段的数据展开:

基表 lateral view explode(列表字段) 单列表 as 列名1

得到的结果是一个基表列表字段 展开得到列名为 列名1单列表基表 合并的特殊表.

5.01, 查询每个商品品类的购买用户数:

select b.category,
count(distinct a.user_name)
from user_goods_category a
lateral view explode(split(category_detail, ',')) b as category
group by b.category;

b.category_c1
book99
clothes110
computer99
electronics99
food105
shoes91

split()将字符串分割并以列表形式返回.

explode()将值为列表形式的字段展开成多行.

from语句后面得到的特殊表如下:

a.user_namea.category_detailb.category
Abbyclothes,food,electronicsclothes
Abbyclothes,food,electronicsfood
Abbyclothes,food,electronicselectronics
Ailsabook,clothes,foodbook
Ailsabook,clothes,foodclothes
Ailsabook,clothes,foodfood

b, 同一字段按分组归类:

5.02, 查看每个商品品类都有哪些用户购买:

select b.category,
collect_set(distinct a.user_name)
from user_goods_category a
lateral view explode(split(category_detail, ',')) b as category
group by b.category;

b.category_c1
book["Ailsa","Alexander",…(后面省略)]
clothes["Abby","Ailsa",...(后面省略)]

collect_set()将分组后分到同一组的值全部放到一个列表里显示出来, 还可以再用 concat_ws('分隔符', ...) 将列表中的值连接成字符串.

6, 表连接优化

  • 使用相同的连接键
    对3个以上表进行 join 连接, on 条件使用相同的连接键, 只会产生一个 MapReduce job.

  • 尽早进行数据过滤
    例如数据只选择需要的区段和字段, 分组去重等.

  • 逻辑过于复杂时引入中间表

7, 防止数据倾斜

数据倾斜: 任务执行过程中, 大部分任务执行完成, 少数任务一直在执行中的情况.

  • 空值产生的数据倾斜
    表连接时, 连接字段有空值, 增加空值过滤条件, 例如:on a.id=b.id and a.id is not null

  • 表连接时, 连接字段数据类型不一致
    将数据类型转换一致, 例如:on a.id=cast(b.id as string)

end

55e715da083eb9e0f7c624ea2ce67fd2.gif       点击下方


推荐阅读
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
author-avatar
郭伟健逍遥_308
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有