Hive JOIN性能调优:从WHERE条件到子查询与分区策略的全方位探索

news/2024/9/24 4:24:16/

文章目录

  • 前言
  • 场景说明
  • 场景一:JOIN前使用WHERE条件
  • 场景二:JOIN后使用WHERE条件
  • 结论
  • 案例
  • 总结

前言

  • 在Hive中,当你执行一个包含JOIN操作的查询时,WHERE条件的使用时机和它对查询性能的影响是一个重要的考虑因素。WHERE条件可以在JOIN操作之前或之后应用,但具体的应用方式会对查询的执行计划和性能产生不同的影响。

场景说明

假设我们有两个表:employees(员工表)和departments(部门表)。employees表包含员工ID、员工姓名和部门ID;departments表包含部门ID和部门名称。

  • employees 表
employee_idnamedepartment_id
1Alice101
2Bob102
3Charlie101
  • departments 表
employee_idname
101Sales
102Engineering

场景一:JOIN前使用WHERE条件

  • 如果你只对某个特定部门的员工感兴趣,比如Sales部门(部门ID为101),你可能会在JOIN之前先过滤employees表。然而,直接在JOIN前过滤通常不是Hive SQL的直接写法,因为Hive通常会在JOIN操作之后再应用WHERE条件(除非你使用了子查询或视图等方式)。但这里我们讨论的是逻辑上的操作顺序。

  • 逻辑上的SQL(非直接Hive SQL写法)

SELECT e.name, d.department_name  
FROM (  SELECT *  FROM employees  WHERE department_id = 101  
) e  
JOIN departments d ON e.department_id = d.department_id;

在这个例子中,我们实际上是通过子查询来模拟在JOIN之前应用WHERE条件的效果。这样做的好处是可以减少参与JOIN操作的数据量,从而提高查询性能。

场景二:JOIN后使用WHERE条件

如果你直接在JOIN之后应用WHERE条件,那么Hive会先执行JOIN操作,然后再过滤结果。

  • 直接的Hive SQL写法
SELECT e.name, d.department_name  
FROM employees e  
JOIN departments d ON e.department_id = d.department_id  
WHERE e.department_id = 101;

虽然这个查询在逻辑上也是正确的,但如果employees表和departments非常大,那么JOIN操作可能会非常耗时,并且会产生大量不必要的数据,这些数据最终会被WHERE条件过滤掉。

结论

在Hive中,为了优化查询性能,尤其是在处理大数据集时,尽量在JOIN之前通过子查询、视图或分区等方式来减少参与JOIN的数据量。这样做可以减少数据的处理量,从而缩短查询时间。不过,也需要注意查询的复杂度和可读性,避免过度优化导致查询难以理解和维护。

案例

SET mapreduce.job.queuename=root.spark;  
SET mapreduce.reduce.memory.mb=4096;
SET mapreduce.map.memory.mb=4096;
--  先查询出集卡车辆
WITH jk AS (SELECT vehicle_no, plate_color_codeFROM ods.ods_collect_dl_02_dw_baseinfo_trans_cert_dfWHERE `date` = ${dt1}AND BUSINESS_SCOPE_CODE LIKE '%02201%'), owner_id AS (-- 车辆和企业关联查询SELECT veh.vehicle_no, veh.plate_color_code, lic.owner_id, lic.owner_nameFROM ods.ods_collect_dl_02_dw_baseinfo_vehicle_df vehJOIN ods.ods_collect_dl_02_dw_info_business_license_df licON veh.`date` = ${dt1}AND lic.`date` = ${dt1}AND veh.owner_id = lic.owner_id), -- 筛选出集卡车辆信息和企业信息jk_veh AS (SELECT jk.vehicle_no, jk.plate_color_code, owner_id.owner_nameFROM jkJOIN owner_idON jk.vehicle_no = owner_id.vehicle_noAND jk.plate_color_code = owner_id.plate_color_code)
-- 集卡车的进出围栏,和车辆停靠点信息
INSERT overwrite directory "/user/cttic/lifeng/ajkj/dt=${dt}" ROW format delimited fields terminated BY "," 
SELECT   
fence.dt, fence.fence_code, fence.veh_no, substr(md5(concat('aj', fence.veh_no, fence.veh_color, 'kj')), 9, 16) AS vehicleno_md5, final_jk.owner_name, from_unixtime(cast(fence.enter_time as int), 'yyyy-MM-dd HH:mm:ss') as enter_time,from_unixtime(cast(fence.out_time as int), 'yyyy-MM-dd HH:mm:ss') as out_time, from_unixtime(cast(stop.start_time as int), 'yyyy-MM-dd HH:mm:ss') as start_time, from_unixtime(cast(stop.end_time as int), 'yyyy-MM-dd HH:mm:ss') as end_time, stop.start_lon, stop.start_lat
FROM (SELECT dt, fence_code, veh_no, veh_color, enter_time, out_time -- substr((md5(concat('aj', veh_no, veh_color, 'kj'))), 9, 16) as vehicleno_md5FROM mid.ct_fence_into_out_dt fenceWHERE fence.dt = ${dt}AND job_id = 'admin_110'AND out_time - enter_time >= 1800AND fence_code IN ('001_lyg', '002_rz', '003_qd')
) fenceJOIN (SELECT vehicle_no, plate_color_code, owner_nameFROM jk_veh) final_jkON final_jk.vehicle_no = fence.veh_noAND final_jk.plate_color_code = fence.veh_colorJOIN (SELECT veh_no, p_color, start_time, end_time, start_lon, start_latFROM dwd.dwd_vehicle_stops_dfWHERE `date` >= ${dt2}AND `date` <= ${dt}AND end_time - start_time > 3600) stopON fence.veh_no = stop.veh_noAND fence.veh_color = stop.p_color;

总结

如果此篇文章有帮助到您, 希望打大佬们能关注点赞收藏评论支持一波,非常感谢大家!
如果有不对的地方请指正!!!


http://www.ppmy.cn/news/1505308.html

相关文章

PHP如何实现登录认证和鉴权

本文由 ChatMoney团队出品 在Web开发中&#xff0c;用户认证&#xff08;Authentication&#xff09;和授权&#xff08;Authorization&#xff09;是构建安全应用程序的核心组件。用户认证是验证用户身份的过程&#xff0c;确保用户是他们声称的那个人。而授权则是确定已认证用…

【八股文】MySQL

1.char 和 varchar的区别 char是定长的&#xff0c;varchar是可变的字符串char适合存长度差不多的或者较短的&#xff0c;例如手机号&#xff0c;身份证&#xff0c;MD4加密算法。varchar用来存备注信息&#xff0c;用户昵称等不确定长度的信息。 2.Decimal、double和float的区…

MySQL——表的约束(一)主键约束

为了防止数据表中插人错误的数据&#xff0c;在 MySQL中&#xff0c;定义了一些维护数据库完整性的规则&#xff0c;表的约束。下表列举了常见的表的约束。 约束条件说明PRIMARY KEY主键约束,用于唯一标识对应的记录FOREIGN KEY外键约束NOT NULL非空约束UNIQUE唯一性约束DEFAU…

Linux中区域设置

Linux中区域设置 sudo locale-gen en_US.UTF-8 sudo update-locale LANGen_US.UTF-8如果您的系统提示 locale-gen 命令未找到&#xff0c;这可能是因为某些发行版的 Linux 系统默认没有安装这个工具 确认Linux发行版本->找到对应的系统安装对应的插件->重新执行命令 1…

数学建模--二分法

目录 二分法的基本原理 应用实例 求解方程根 查找有序数组中的元素 注意事项 Python代码示例 ​编辑 延伸 二分法在数学建模中的具体应用案例有哪些&#xff1f; 如何选择二分法的初始区间以确保收敛速度和精度&#xff1f; 在使用二分法求解方程时&#xff0c;如何…

macOS Ventura系统简介

macOS Ventura 引入了许多新特性&#xff0c;具体请登录官网查询&#xff1a; 1. **台前调度&#xff08;Stage Manager&#xff09;**&#xff1a;这是一项新的窗口管理功能&#xff0c;可以帮助用户更有效地组织和切换他们的应用程序和窗口。 2. **系统级的天气应用**&…

【C++】对象模型和this指针

目录 一、成员变量和成员函数分开存储 二、this指针概念 三、空指针访问成员函数 四、const修饰成员函数 一、成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 ①C编译器会给每一个空对象分配一个字节的空间&#xff0c;为了区分空对象占内存的位置 clas…

Dockerfile 容器镜像制作 私有仓库

Dockerfile 概述 制作镜像 FROM CMD # ENTRYPOINT 与 CMD 执行方式为 ${ENTRYPOINT} ${-${CMD}} apache 镜像 nginx 镜像 php-fpm 镜像 docker 私有仓库