Hive SQL 优化案例详解

本贴最后更新于 1688 天前,其中的信息可能已经时移世改

HiveSQL 经典优化案例一:
1.1 将要执行的查询(执行了 1 个多小时才出结果):

SELECT dt as DATA_DATE,STRATEGY,AB_GROUP,SOURCE,     count(distinct case when lower(event) not like '%push%' and event!='corner_mark_show' then udid else null end) as DAU,     count(case when event='client_show' then 1 else null end) as TOTAL_VSHOW,     count(distinct case when event='client_show' then vid else null end) as TOTAL_VIDEO_VSHOW,     count(case when event='video_play' then 1 else null end) as TOTAL_VV_VP,     count(distinct case when event='video_play' then udid else null end) as TOTAL_USERS_VP,     count(case when event='effective_play' then 1 else null end) as TOTAL_VV_EP,     count(distinct case when event='effective_play' then udid else null end) as TOTAL_USERS_EP,     sum(case when event='video_over' then duration else 0 end) as TOTAL_DURATION,     count(case when event='video_over' then 1 else null end) as TOTAL_VOVER,     sum(case when event='video_over' then play_cnts else 0 end) as TOTAL_VOVER_PCNTS,     count(case when event='push_video_clk' then 1 else null end) as TOTAL_PUSH_VC,     count(distinct case when event='app_start' and body_source = 'push' then udid else null end) as TOTAL_PUSH_START,     count(case when event='post_comment' then 1 else null end) as TOTAL_REPLY,     count(distinct case when event='post_comment' then udid else null end) as TOTAL_USERS_REPLY     FROM dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_zkl group by dt,strategy,ab_group,source;复制代码

1.2 查询语句涉及到的表有 7.7 亿 + 数据。(查询如下)

jdbc:hive2://ks-hdp-master-01.dns.rightpad (default)> select count(*) from dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_zkl; 复制代码

1.3 优化思路:既然将要执行的查询是按照 dt, strategy, ab_group, source 这 4 个字段分组, 那么在建表的时候,就按这四个字段中的 N 个(1 或 2 或 3 或 4)个字段组合分区,直接让 count(distinct xx) 之类的查询定位到“更少的数据子集”,其执行效率就应该更高了(不需要每个子任务均从 7.7 亿 + 的数据中(去重)统计)。

1.4 先看每个字段将会有多少分区(因为 Hive 表分区也不宜过多,一般一个查询语句涉及到的 hive 分区 应该控制在 2K 内)

jdbc:hive2://ks-hdp-master-01.dns.rightpad (default)> select count(distinct dt) as dis_dt, count(distinct strategy) as dis_strategy, count(distinct ab_group) as dis_ab_group, count(distinct source) as dis_source from dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_zkl;复制代码

[hue@ks-hdp-client-v02 10:55:08 /usr/local/hue]$ python Python 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 2*14*72 2016 -- 2016 个分区还可以接受。复制代码

1.5 根据原表,新建分区表,并将原表数据插入新表:

show create table dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_zkl; 复制代码
jdbc:hive2://ks-hdp-master-01.dns.rightpad (default)> show create table dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_zkl; 复制代码

创建新表:按 dt,source,stragegy,ab_group 分区(注意先后顺序,一般习惯分区数越少的越靠前,根据 1.5 的查询可知:dt=1,source=2,strategy=14,ab_group=72)

create external table `dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_lym`(   event string,   udid string,   vid string,   duration string,   body_source string,   play_cnts string )PARTITIONED BY (   dt string,   source string,   strategy string,   ab_group string );复制代码

将原表数据插入新表:

insert into `dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_lym` partition(dt,source,strategy,ab_group) select event,udid,vid,duration,body_source,play_cnts,dt,source,strategy,ab_group from `dwb_v8sp_tmp.base_report_bystrategy_byab_source_column_zkl`;复制代码

核对两表的数据是否一致:

1.6 基于新表执行查询(执行 5 分钟出结果):

HiveSQL 经典优化案例二:

问题描述:一个复杂的 SQL,查询执行一段时间后报错:基本上是查不出来;

分析函数对于大表来说不是 hive 的强项,这个时候我们将其分解成很多子集,并且合理利用 hive 分区表的优势,然后去 join 。

2.1 将要执行的查询

create table bi_tmp.aloha_UserLoyalty_190301_190303 as     select aid, imei, idfa, udid, event, duration, dt, time_local, hour, source,         first_value(time_local) over(partition by udid, event order by time_local) as first_time,         last_value(time_local) over(partition by udid, event order by time_local) as last_time,         count(time_local) over(partition by udid, event, dt) as event_count_per_day,         sum(duration) over(partition by udid, event, dt) as event_duration_each_day     from dwb_v8sp.event_column_info_new_hour     where event in ('app_start', 'app_exit', 'effective_play', 'share_succ', 'like', 'unlike', 'like_comment', 'unlike_comment',         'comment_success')         and dt >= '2019-03-01' and dt <= '2019-03-03'; select count(*) from dwb_v8sp.event_column_info_new_hour where event in ('app_start', 'app_exit', 'effective_play', 'share_succ', 'like', 'unlike', 'like_comment', 'unlike_comment', 'comment_success') and dt >= '2019-03-01' and dt <= '2019-03-03'; 复制代码

select count(distinct event) as dis_event from dwb_v8sp.event_column_info_new_hour where event in ('app_start', 'app_exit', 'effective_play', 'share_succ', 'like', 'unlike', 'like_comment', 'unlike_comment', 'comment_success') and dt >= '2019-03-01' and dt <= '2019-03-03';复制代码

分解成三个子集,并保存到三张表: bi_tmp.zyt1, bi_tmp.zyt2, bi_tmp.zyt3

-- drop table if exists bi_tmp.zyt1; create table bi_tmp.zyt1 partitioned by(event) as select udid,        min(time_local) as first_time,        max(time_local) as last_time,        event from dwb_v8sp.event_column_info_new_hour where event in ('app_start', 'app_exit', 'effective_play', 'share_succ', 'like', 'unlike', 'like_comment', 'unlike_comment', 'comment_success') and dt >= '2019-03-01' and dt <= '2019-03-03' group by udid, event; -- drop table if exists bi_tmp.zyt2 purge; create table bi_tmp.zyt2 partitioned by(dt,event) as select udid,        count(time_local) as event_count_per_day,        sum(duration) as event_duration_each_day,        dt,       event from dwb_v8sp.event_column_info_new_hour where event in ('app_start', 'app_exit', 'effective_play', 'share_succ', 'like', 'unlike', 'like_comment', 'unlike_comment', 'comment_success') and dt >= '2019-03-01' and dt <= '2019-03-03' group by udid, dt, event; create table bi_tmp.zyt3 partitioned by(dt,event) as select aid, imei, idfa, udid, duration, time_local, hour, source, dt, event from dwb_v8sp.event_column_info_new_hour t3     where event in ('app_start', 'app_exit', 'effective_play', 'share_succ', 'like', 'unlike', 'like_comment', 'unlike_comment',         'comment_success')         and dt >= '2019-03-01' and dt <= '2019-03-03'; -- 插入目标表: create table bi_tmp.aloha_UserLoyalty_190301_190303 as     select t3.aid, t3.imei, t3.idfa, t3.udid, t3.event, t3.duration, t3.dt, t3.time_local, t3.hour, t3.source,         t1.first_time,        t1.last_time,        t2.event_count_per_day,        t2.event_duration_each_day    from bi_tmp.zyt1 t1 join bi_tmp.zyt2 t2 on t1.event=t2.event and t1.udid=t2.udid     join bi_tmp.zyt3 t3 on t2.dt=t3.dt and t2.event= t3.event and t2.udid=t3.udid; -- 验证数据:(与上面的查询记录行数对的上)复制代码

HiveSQL 经典优化案例三:

如下 SQL,用到了 PERCENTILE_APPROX 函数,问题描述:如下 SQL,用到了 PERCENTILE_APPROX 函数,个人初步分析认为:由于用到该函数的次数太多,导致性能严重下降。

我仔细查了一下该函数,发现:它是支持“数组传参”的,那么就不难找到优化该 SQL 的方法了。

3.1 原 SQL 性能测试:

3.2 优化后的 SQL,性能测试:

优化后的 SQL,性能提升了 4 倍多。

  • Hive
    22 引用 • 7 回帖 • 1 关注
  • HiveSQL
    1 引用
  • SQL
    129 引用 • 392 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • sts
    2 引用 • 2 回帖 • 230 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖
  • 招聘

    哪里都缺人,哪里都不缺人。

    188 引用 • 1057 回帖
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • V2Ray
    1 引用 • 15 回帖 • 1 关注
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    25438 引用 • 105216 回帖
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 3 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 628 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 166 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 181 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 117 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 636 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖 • 1 关注
  • 反馈

    Communication channel for makers and users.

    121 引用 • 907 回帖 • 273 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 8 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2040 回帖
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    24 引用 • 241 回帖
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 655 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 363 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 91 关注
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 544 关注