HIVE 中内连接(join on )与left semi join 查询结果不一致的分析(两者区别)

2024-06-10 04:32

本文主要是介绍HIVE 中内连接(join on )与left semi join 查询结果不一致的分析(两者区别),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、第一种讲解

LEFT SEMI JOIN (左半连接)是 IN/EXISTS 子查询的一种更高效的实现

Hive 当前没有实现 IN/EXISTS 子查询,所以可以用 LEFT SEMI JOIN 重写你的子查询语句

示例

可以改写为

特点

1、left semi join 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。

2、left semi join 是只传递表的 join key 给 map 阶段,因此left semi join 中最后 select 的结果只许出现左表。

3、因为 left semi join 是 in(keySet) 的关系,遇到右表重复记录,左表会跳过,而 join 则会一直遍历。这就导致右表有重复值得情况下 left semi join 只产生一条,join 会产生多条,也会导致 left semi join 的性能更高。 

比如以下A表和B表进行 join 或 left semi join,然后 select 出所有字段,结果区别如下:

二、第二种讲解

重点:由于子表(tmall_data_fdi_dim_main_auc)中存在重复的数据,当使用JOIN ON的时候,A,B表会关联出两条记录,应为ON上的条件符合; 
而是用LEFT SEMI JOIN 当A表中的记录,在B表上产生符合条件之后就返回,不会再继续查找B表记录了,所以如果B表有重复,也不会产生重复的多条记录。 

由于HIVE中都是等值连接,在JOIN使用的时候,有两种写法在理论上是可以达到相同的效果的,但是由于实际情况的不一样,子表中数据的差异导致结果也不太一样。 
  
写法一: 

Java代码 

  1. select  
  2.            a.bucket_id,  
  3.         a.search_type,  
  4.             a.level1,  
  5.         a.name1,  
  6.         a.level2,  
  7.         a.name2,  
  8.         cast((a.alipay_fee) as double) as zhuliu_alipay,  
  9.         cast(0 as double) as total_alipay  
  10.         from tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a  
  11.      left semi join  
  12.      tmall_data_fdi_dim_main_auc b  
  13.      on (a.level2 = b.cat_id2  
  14.          and a.brand_id = b.brand_id  
  15.        and b.cat_id2 > 0  
  16.          and b.brand_id > 0  
  17.          and b.max_price = 0  
  18.      )  


3121 条 


写法二: 
Java代码 

  1. select  
  2.            a.bucket_id,  
  3.         a.search_type,  
  4.             a.level1,  
  5.         a.name1,  
  6.         a.level2,  
  7.         a.name2,  
  8.         cast((a.alipay_fee) as double) as zhuliu_alipay,  
  9.         cast(0 as double) as total_alipay  
  10.         from tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a  
  11.      join   tmall_data_fdi_dim_main_auc b  
  12.      on (a.level2 = b.cat_id2  
  13.          and a.brand_id = b.brand_id)  
  14.   where  b.cat_id2 > 0  
  15.          and b.brand_id > 0  
  16.          and b.max_price = 0  



结果是:3142 


这两种写法带来的值居然不是相等的,我一直以为理解这两种方式的写法是一样的, 
但是统计的结果却是不一样的。 
目前还没有搞清楚是什么原因,谁能那个搞清楚呢。 


经过一层一层的查找,发现是由于子表(tmall_data_fdi_dim_main_auc)中存在重复的数据,当使用JOIN ON的时候,A,B表会关联出两条记录,应为ON上的条件符合; 
而是用LEFT SEMI JOIN 当A表中的记录,在B表上产生符合条件之后就返回,不会再继续查找B表记录了,所以如果B表有重复,也不会产生重复的多条记录。 

大多数情况下JOIN ON 和left semi on是对等的,但是在上述情况下会出现重复记录。大家以后可要小心。

这篇关于HIVE 中内连接(join on )与left semi join 查询结果不一致的分析(两者区别)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1047216

相关文章

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

MySQL中VARCHAR和TEXT的区别小结

《MySQL中VARCHAR和TEXT的区别小结》MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解... 目录一、VARCHAR 和 TEXT 基本介绍1. VARCHAR2. TEXT二、VARCHAR

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

MySQL之复合查询使用及说明

《MySQL之复合查询使用及说明》文章讲解了SQL复合查询中emp、dept、salgrade三张表的使用,涵盖多表连接、自连接、子查询(单行/多行/多列)及合并查询(UNION/UNIONALL)等... 目录复合查询基本查询回顾多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使