Hive的Join连接

news2025/1/19 10:21:59

前言

  Hive-3.1.2版本支持6种join语法。分别是:inner join(内连接)、left join(左连接)、right join(右连接)、full outer join(全外连接)、left semi join(左半开连接)、cross join(交叉连接,也叫做笛卡尔乘积)。

一、Hive的Join连接

数据准备: 有两张表studentInfo、studentScore

create table if not exists studentInfo
(
    user_id   int comment '学生id',
    name      string comment '学生姓名',
    gender    string comment '学生性别'
)
    comment '学生信息表';
INSERT overwrite table studentInfo
VALUES (1, '吱吱', '男'),
       (2, '格格', '男'),
       (3, '纷纷', '女'),
       (4, '嘻嘻', '女'),
       (5, '安娜', '女');


create table if not exists studentScore
(
    user_id   int comment '学生id',
    subject   string comment '学科',
    score     int comment '分数'
)
    comment '学生分数表';

INSERT overwrite table studentScore
VALUES (1, '生物', 78),
       (2, '生物', 88),
       (3, '生物', 34),
       (4, '数学', 98),
       (null, '数学', 64);

1.1 inner join 内连接

       内连接是最常见的一种连接,其中inner可以省略:inner join == join ; 只有进行连接的两个表中都存在与连接条件相匹配的数据才会被留下来。

select
    t1.user_id,
    t1.name,
    t1.gender,
    t2.subject,
    t2.score
from studentInfo t1
        inner join studentScore t2 on t1.user_id = t2.user_id

1.2 left join 左外连接

    join时以左表的全部数据为准,右边与之关联;左表数据全部返回,右表关联上的显示返回,关联不上的显示null返回。

select
    t1.user_id,
    t1.name,
    t1.gender,
    t2.user_id,
    t2.subject,
    t2.score
from studentInfo t1
 left  join studentScore t2 
   on t1.user_id = t2.user_id;

1.3 right join 右外连接

       join时以右表的全部数据为准,左边与之关联;右表数据全部返回,左表关联上的显示返回,关联不上的显示null返回。

select
    t2.user_id,
    t2.subject,
    t2.score,
    t1.user_id,
    t1.name,
    t1.gender
from studentInfo t1
 right  join studentScore t2
   on t1.user_id = t2.user_id;

1.4 full join 满外连接

  包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行;在功能上等价于对这两个数据集合分别进行左外连接和右外连接,然后再使用消去重复行的操作将上述两个结果集合并为一个结果集。full join 本质等价于 left join  union   right join; 

select
    t1.user_id,
    t1.name,
    t1.gender,
    t2.user_id,
    t2.subject,
    t2.score
from studentInfo t1
 full  join studentScore t2
   on t1.user_id = t2.user_id;

ps:full join 本质等价于 left join union  right join; 

select
    t1.user_id,
    t1.name,
    t1.gender,
    t2.user_id,
    t2.subject,
    t2.score
from studentInfo t1
 full  join studentScore t2
   on t1.user_id = t2.user_id;

----- 等价于下述代码

select
    t1.user_id as t1_user_id ,
    t1.name,
    t1.gender,
    t2.user_id as  t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
 left  join studentScore t2
   on t1.user_id = t2.user_id
union
select
    t1.user_id as t1_user_id ,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
 right  join studentScore t2
   on t1.user_id = t2.user_id

1.5 多表连接

      注意:连接 n 个表,至少需要 n-1 个连接条件。例如:连接三个表,至少需要两个连接
条件。 join on使用的key有几组就会被转化为几个MR任务,使用相 同的key来连接,则只会被转化为1个MR任务。

1.6 cross join 交叉连接

    交叉连接cross join,将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积 N*M。对于大表来说,cross join慎用(笛卡尔积可能会造成数据膨胀

    在SQL标准中定义的cross join就是无条件的inner join。返回两个表的笛卡尔积,无需指定关联 键。
  在HiveSQL语法中,cross join 后面可以跟where子句进行过滤,或者on条件过滤。

    
---举例:
select
    t1.user_id as t1_user_id ,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1, studentScore t2

--- 等价于:
select
     t1.user_id as t1_user_id ,
     t1.name,
     t1.gender,
     t2.user_id as t2_user_id,
     t2.subject,
     t2.score
from studentInfo t1
 join studentScore t2

---等价于:
select
     t1.user_id as t1_user_id ,
     t1.name,
     t1.gender,
     t2.user_id as t2_user_id,
     t2.subject,
     t2.score
from studentInfo t1
 cross  join studentScore t2

1.7 join on和where条件区别

       两者之间的区别见文章:
Hive中left join 中的where 和 on的区别-CSDN博客文章浏览阅读1.2k次,点赞21次,收藏23次。Hive中left join 中的where 和 on的区别https://blog.csdn.net/SHWAITME/article/details/135892183?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170780016016800197016026%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170780016016800197016026&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-135892183-null-null.nonecase&utm_term=where&spm=1018.2226.3001.4450

1.8 join中不能有null

  • group by字段为null,会导致结果不正确(null值也会参与group by 分组)

group by column1
  • join字段为null会导致结果不正确(例如:下述 t2.b字段是null值)
t1 left join t2 on t1.a=t2.a and t1.b=t2.b 

1.9 join操作导致数据膨胀

select *
from a 
left join b 
on a.id = b.id 

     如果主表a的id是唯一的,副表b的id有重复值,非唯一,那当on a.id = b.id 时,就会导致数据膨胀(一条变多条)。因此两表或多表join的时候,需保证join的字段唯一性,否则会出现一对多的数据膨胀现象。

二、Hive的谓词下推

2.1 谓词下推概念

      在不影响结果的情况下,尽量将过滤条件提前执行。谓词下推后,过滤条件在map端执行,减少了map端的输出,降低了数据在集群上传输的量,提升任务性能。

     在hive生成的物理执行计划中,有一个配置项用于管理谓词下推是否开启。

set hive.optimize.ppd=true; 默认是true

   疑问:如果hive谓词下推的功能与join同时存在,那下推功能可以在哪些场景下生效

2.2 谓词下推场景分析

     数据准备:以上述两张表studentInfo、studentScore为例

    查看谓词下推是否开启:set hive.optimize.ppd;

(1) inner join 内连接

  • 对左表where过滤
 explain
select
    t1.user_id as t1_user_id,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
    inner join studentScore t2 on t1.user_id = t2.user_id
where t1.user_id >2

     explain查看执行计划,在对t2表进行scan后,优先对t1表进行filter,过滤t1.user_id >2,即谓词下推生效。

  • 对右表where过滤
 explain
select
    t1.user_id as t1_user_id,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
    inner join studentScore t2 on t1.user_id = t2.user_id
where t2.user_id is not null

    explain查看执行计划,在对t2表进行scan后,优先进行filter,过滤t2.user_id is not null,即谓词下推生效。

 

  • 对左表on过滤
explain
select
    t1.user_id as t1_user_id,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
    inner join studentScore t2 on t1.user_id = t2.user_id and t1.user_id >2

    explain查看执行计划,在对t2表进行scan后,优先对t1表进行filter,过滤t1.user_id >2,即谓词下推生效。

  • 对右表on过滤
 explain
select
    t1.user_id as t1_user_id,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
    inner join studentScore t2 on t1.user_id = t2.user_id and t2.user_id is not null

    explain查看执行计划,在对t2表进行scan后,优先进行filter,过滤t2.user_id is not null,即谓词下推生效。 

 (2) left join(right join 同理)

  • 对左表where过滤
explain
select
    t1.user_id,
    t1.name,
    t1.gender,
    t2.user_id,
    t2.subject,
    t2.score
from studentInfo t1
 left  join studentScore t2
   on t1.user_id = t2.user_id
where t1.user_id >2;

    explain查看执行计划,在对t2表进行scan后,优先对t1表进行filter,过滤t1.user_id >2,即谓词下推生效。

  • 对右表where过滤
explain
select
    t1.user_id,
    t1.name,
    t1.gender,
    t2.user_id,
    t2.subject,
    t2.score
from studentInfo t1
 left  join studentScore t2
   on t1.user_id = t2.user_id
where t2.user_id is not null;

     explain查看执行计划,在对t2表进行scan后,优先进行filter,过滤t2.user_id is not null,即谓词下推生效。 

 

  • 对左表on过滤
explain 
select
    t1.user_id as t1_user_id,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
   left join studentScore t2
     on t1.user_id = t2.user_id and t1.user_id >2

      explain查看执行计划,在对t2表进行scan后,在对t1表未进行filter,即谓词下推不生效

 

  • 对右表on过滤
explain
select
    t1.user_id as t1_user_id,
    t1.name,
    t1.gender,
    t2.user_id as t2_user_id,
    t2.subject,
    t2.score
from studentInfo t1
   left join studentScore t2
     on t1.user_id = t2.user_id and t2.user_id is not null;

      explain查看执行计划,在对t2表进行scan后,优先进行filter,过滤t2.user_id is not null,即谓词下推生效。 

 (3) full join

  • 对左表where过滤
explain 
select
     t1.user_id as t1_user_id,
     t1.name,
     t1.gender,
     t2.user_id as t2_user_id,
     t2.subject,
     t2.score
from studentInfo t1
 full  join studentScore t2
   on t1.user_id = t2.user_id
where  t1.user_id >2 ;

     explain查看执行计划,在对t2表进行scan后,优先对t1表进行filter,过滤t1.user_id >2,即谓词下推生效。

 

  • 对右表where过滤
explain
select
     t1.user_id as t1_user_id,
     t1.name,
     t1.gender,
     t2.user_id as t2_user_id,
     t2.subject,
     t2.score
from studentInfo t1
 full  join studentScore t2
   on t1.user_id = t2.user_id
where  t2.user_id is not null

     explain查看执行计划,在对t1 表进行scan后,优先进行filter,过滤t2.user_id is not null,即谓词下推生效。 

  • 对左表on过滤
explain
select
     t1.user_id as t1_user_id,
     t1.name,
     t1.gender,
     t2.user_id as t2_user_id,
     t2.subject,
     t2.score
from studentInfo t1
 full  join studentScore t2
   on t1.user_id = t2.user_id and t1.user_id >2;

       explain查看执行计划,在对t1表进行scan后,未对t1表进行filter,即谓词下推不生效

  • 对右表on过滤
explain
select
     t1.user_id as t1_user_id,
     t1.name,
     t1.gender,
     t2.user_id as t2_user_id,
     t2.subject,
     t2.score
from studentInfo t1
 full  join studentScore t2
   on t1.user_id = t2.user_id and t2.user_id is not null;

     explain查看执行计划,在对t1表进行scan后,未对t2表未进行filter,即谓词下推不生效

总结:

hive中谓词下推的各种场景下的生效情况如下表:

inner joinleft joinright joinfull join
左表右表左表右表左表右表左表右表
where条件
on条件××××

三、Hive Join的数据倾斜

          待补充

参考文章:

Hive的Join操作_hive join-CSDN博客

《Hive用户指南》- Hive的连接join与排序_hive 对主表排序后连接查询能保持顺序吗-CSDN博客

Hive 中的join和谓词下推_hive谓词下推-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ bfs再探迷宫游戏(五十五)【第二篇】

今天我们用bfs解决迷宫游戏。 1.再探迷宫游戏 前面我们已经接触过了迷宫游戏,并且学会了如何使用 DFS 来解决迷宫最短路问题。用 DFS 求解迷宫最短路有一个很大的缺点,需要枚举所有可能的路径,读入的地图一旦很大,可能的搜索方案…

VM和Linux安装

VM和Linux安装 一、下载VM 1.官网地址:https://www.vmware.com/cn.html 2.其他地址:http://ww7.nocmd.com/windows/740.html 许可证这个,大家可以自己上网搜索,很容易就搜索到就可以使用了 上面内容就是安装VM的步骤 安…

BFS与DFS初级练习(排列数字,n-皇后,走迷宫)

BFS与DFS初步了解 DFS(深度优先搜索)和BFS(广度优先搜索)是两种常用的图遍历算法。 DFS是一种递归的搜索算法,它从起始节点开始,沿着路径依次访问与当前节点相邻的未访问节点,直到无法继续访问…

Pytorch的可视化

1 使用 wandb进行可视化训练过程 本文章将从wandb的安装、wandb的使用、demo的演示进行讲解。 1.1 如何安装wandb? wandb的安装比较简单,在终端中执行如下的命令即可: pip install wandb在安装完成之后,我们需要,去…

【力扣】5.最长回文子串

这道题我主要是通过动态规划来进行解题,看了我好久(解析),生疏了呀。 首先就是判断一个字符串是不是回文,我们可以设置两个指针,从前往后进行判断即可,运用暴力解题法,这里运用的动…

【C++】内存详解(堆,栈,静态区)

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

【FPGA】VHDL:八段码到8421BCD码转换电路

目录 EDA设计基础练习题 : 实验要求如下: 代码 八段码到8421BCD码转换电路 8421BCD码到八段码转换电路 八段码到8421BCD~运行结果展示 8421BCD转八段码~运行结果展示 特别注意 软件:Quartus II 13.0 (64-bit) 语言:VHDL E…

书生谱语-基于 InternLM 和 LangChain 搭建知识库

大语言模型与外挂知识库(RAG)的优缺点 RAG方案构建与优化 作业 在创建web_demo时,需要根据教程将服务器端口映射到本地端口,另外需要将链接的demo从服务器中复制出来,不要直接从服务器打开demo页面,不然会…

Blazor OIDC 单点登录授权实例5 - 独立SSR App (net8 webapp ) 端授权

目录: OpenID 与 OAuth2 基础知识Blazor wasm Google 登录Blazor wasm Gitee 码云登录Blazor OIDC 单点登录授权实例1-建立和配置IDS身份验证服务Blazor OIDC 单点登录授权实例2-登录信息组件wasmBlazor OIDC 单点登录授权实例3-服务端管理组件Blazor OIDC 单点登录授权实例4 …

低资源学习与知识图谱:构建与应用

目录 前言1 低资源学习方法1.1 数据增强1.2 特征增强1.3 模型增强 2 低资源知识图谱构建与推理2.1 元关系学习2.2 对抗学习2.3 零样本关系抽取2.4 零样本学习与迁移学习2.5 零样本学习与辅助信息 3 基于知识图谱的低资源学习应用3.1 零样本图像分类3.2 知识增强的零样本学习3.3…

鸿蒙小案例-你画我猜

鸿蒙小案例-你画我猜 1.准备组件(组件布局) 2.实现跟随鼠标画笔画出图案功能 3.实现复制上面的画笔的图案功能 4.其他小功能1.组件的准备 画布的组件官方给的API是Canvas,需要传递一个参数CanvasRenderingContext2D 直接搜索API 使用官方案例 private settings: …

【GO语言卵细胞级别教程】05.项目创建和函数讲解

感谢!点点赞和评论呀!我将继续更新 目录: 感谢!点点赞和评论呀!我将继续更新0.创建项目1.函数的引入2.注意事项3.详细介绍3.1 形参介绍 4.导入包4.1 基本知识4.2 注意事项 5.init函数6.匿名函数 0.创建项目 创建目录 …

力扣精选算法100道——矩阵区域和 (前缀和专题)

目录 🎈了解题意 🎈算法原理 🎈实现代码 🎈了解题意 给定一个大小为 m x n 的矩阵 mat 和一个整数 k,你需要计算一个新的矩阵 answer,其中每个 answer[i][j] 表示矩阵 mat 中以坐标 (i, j) 为中心、边…

JavaScript 事件循环:Event Loop

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 事件循环 是 web 开发中的一个核心概念,它是 JavaScript…

【Linux】线程概念和线程控制

线程概念 一、理解线程1. Linux中的线程2. 重新定义线程和进程3. 进程地址空间之页表4. 线程和进程切换5. 线程的优点6. 线程的缺点7. 线程异常8. 线程用途9. 线程和进程 二、线程控制1. pthread 线程库(1)pthread_create()(2)pth…

[Doris] Doris的安装和部署 (二)

文章目录 1.安装要求1.1 Linux操作系统要求1.2 软件需求1.3 注意事项1.4 内部端口 2.集群部署2.1 操作系统安装要求2.2 下载安装包2.3 解压2.4 配置FE2.5 配置BE2.6 添加BE2.7 FE 扩容和缩容2.8 Doris 集群群起脚本 3.图形化 1.安装要求 1.1 Linux操作系统要求 1.2 软件需求 1…

Acwing---842.排列数字

排列数字 1.题目2.基本思想3.代码实现 1.题目 给定一个整数 n,将数字 1∼n排成一排,将会有很多种排列方法。 现在,请你按照字典序将所有的排列方法输出。 输入格式 共一行,包含一个整数 n。 输出格式 按字典序输出所有排列方案…

mysql Day05

sql性能分析 sql执行频率 show global status like Com_______ 慢查询日志 执行时间超过10秒的sql语句 profile详情 show profiles帮助我们了解时间都耗费到哪里了 #查看每一条sql的耗时情况 show profiles#查看指定query_id的sql语句各个阶段的耗时情况 show profile fo…

【电路笔记】-并联电感

并联电感 文章目录 并联电感1、概述2、并联电感示例13、互耦并联电感器4、并联电感示例25、并联电感示例36、总结当电感器的两个端子分别连接到另一个或多个电感器的每个端子时,电感器被称为并联连接在一起。 1、概述 所有并联电感器上的压降将是相同的。 然后,并联的电感器…

MATLAB 1:基础知识

MATLAB中的数据类型主要包括数值类型、逻辑类型、字符串、函数句柄、结构体和单元数组类型。这六种基本的数据类型都是按照数组形式存储和操作的。 MATLAB中还有两种用于高级交叉编程的数据类型,分别是用户自定义的面向对象的用户类类型和Java类类型。 1.1.1数值类…