筛选条件在on和where中的区别(基于hivesql)

理解筛选条件在on和where中的区别,最好先理解sql的执行顺序,尽管实际执行时不同的物理执行引擎可能会有特定的优化,但是逻辑执行顺序必须遵循:

1)from:确定数据源是什么,from后可以是单表,可以是多表的join操作。

2)where:对from的数据源进行筛选。

3)group by:对where筛选后的结果分组。

4)having:对group by分组后的结果进行过滤(注意此时过滤的数据粒度不是单条记录,而是整个分组)。

5)select:选择结果字段(窗口函数的执行时机也在此时)。

6)order by:对select的结果执行排序。

7)limit:限制最终的结果数量。

所以从执行顺序可以看出筛选条件放在where和on中,最本质的区别是过滤的时机不同,on中的过滤发生在join的过程中,影响的是匹配逻辑,并不影响参与关联的数据集本身。而where中的过滤是对join之后的结果集进行过滤。

筛选条件放在on中:

sql 复制代码
drop view if exists employees;
create temporary view employees as
select 1 as emp_id, '张三' as name, 10 as dept_id
union all
select 2, '李四', 20
union all
select 3, '王五', null;

drop view if exists departments;
create temporary view departments as
select 10 as dept_id, '技术部' as dept_name, 'active' as status
union all
select 20, '市场部', 'inactive'
union all
select 30, '财务部', 'active';

select 
  *
from employees e
left join departments d on e.dept_id=d.dept_id and d.status='active';

保留了左表的全部记录,逻辑上和先从右表筛选,拿筛选后的结果和左表关联的效果一样。

放在where中:

sql 复制代码
drop view if exists employees;
create temporary view employees as
select 1 as emp_id, '张三' as name, 10 as dept_id
union all
select 2, '李四', 20
union all
select 3, '王五', null;

drop view if exists departments;
create temporary view departments as
select 10 as dept_id, '技术部' as dept_name, 'active' as status
union all
select 20, '市场部', 'inactive'
union all
select 30, '财务部', 'active';

select 
  *
from employees e
left join departments d on e.dept_id=d.dept_id where d.status='active';

tips

执行逻辑上,on只影响匹配逻辑,而不影响参与关联匹配的数据集本身,因此如果在左连接 left join 中用on对左表进行条件限制,左表依然会全部保留。

sql 复制代码
drop view if exists employees;
create temporary view employees as
select 1 as emp_id, '张三' as name, 10 as dept_id
union all
select 2, '李四', 20
union all
select 3, '王五', null;

drop view if exists departments;
create temporary view departments as
select 10 as dept_id, '技术部' as dept_name, 'active' as status
union all
select 20, '市场部', 'inactive'
union all
select 30, '财务部', 'active';

select 
  *
from employees e
left join departments d on e.dept_id=d.dept_id and e.dept_id is not null;

实际执行中,物理执行引擎在不影响结果集的前提下也会进行一定的优化,主要优化逻辑就是将参与关联的数据提早过滤,https://blog.csdn.net/atwdy/article/details/139125669 中对不同情况下的执行计划进行过详细的分析。

相关推荐
时差9535 个月前
Flink维表join
大数据·flink·join·维表
PersistJiao5 个月前
Spark RDD各种join算子从源码层分析实现方式
spark·rdd·算子·join
DBdoctor官方6 个月前
SQL性能优化指南:如何优化MySQL多表join场景
sql·mysql·性能优化·join·多表join
大王只是带我巡了个山7 个月前
优化 OR 条件过多导致的查询超时
数据库·mysql·join·or 优化·or 超时·查询超时
ZZDICT7 个月前
SQL 多表联查
join·is null·三表联查·四表联查
教练、我想打篮球8 个月前
50 mysql 的 “where 1 = 1“ 的优化处理
mysql·where·always·optimize
atwdy10 个月前
【HiveSQL】join关联on和where的区别及效率对比
hive·sql·where·on
努力的派大星星1 年前
深入浅出地探讨Python中字符串拼接的原理及效率优化方法
开发语言·python·字符串拼接·join
LostSpeed1 年前
用WHERE命令可以在命令行搜索文件
c·file·find·where