? ? 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。on、where、having就是在这个过程中对数据进行过滤。
? ? on是在生成中临时表之前就去作用的,它会在数据源那里就把不符合要求的数据给过滤掉,所以on运行的速度最快。
? ? where和having是在临时表生产之后,对临时表中的数据进行过滤用的。having一般会用在聚合函数之后,比如name, sum(money) as tatal ...groupy by name having total > 500。而且查到where在处理时会使用rushmore技术,having不能。所以同样是在没有聚合函数的场景下使用时,where的速度比having要快。
left jion时,on和where条件的区别:
假设有两张表:
表1:tab2
表2:tab2
size | name | 10 | AAA | 20 | BBB | 20 | CCC |
两条SQL: 1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’ 2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)
第一条SQL的过程:
1、中间表 on条件:? tab1.size = tab2.size |
tab1.id | tab1.size | tab2.size | tab2.name | 1 | 10 | 10 | AAA | 2 | 20 | 20 | BBB | 2 | 20 | 20 | CCC | 3 | 30 | (null) | (null) |
| | | | | 2、再对中间表过滤 where 条件: tab2.name=’AAA’ |
tab1.id | tab1.size | tab2.size | tab2.name | 1 | 10 | 10 | AAA |
| | |
|
第二条SQL的过程:
1、中间表 on条件:? tab1.size = tab2.size and tab2.name=’AAA’ (条件不为真也会返回左表中的记录) |
tab1.id | tab1.size | tab2.size | tab2.name | 1 | 10 | 10 | AAA | 2 | 20 | (null) | (null) | 3 | 30 | (null) | (null) |
|
|
? ? left join 会返回左边表的全部记录。因为on条件会下推到数据源加载数据的时候对数据进行过滤,所以只会把tab2.name=’AAA’的记录拉去出来进行join。size不匹配时,右边的值为null,最后生成的临时表就是最终的结果记录表。所以on中的条件不管是为true还是false,left join时一定会返回左表中的全部记录,右边不匹配的字段为null。
? ? 而where条件则是left join 生产临时表之后,对临时表中的所有数据进行过滤,最后只会保留tab2.name=’AAA’的记录。
参考:
????????on条件与where条件的区别_xiepeifeng的专栏-CSDN博客(on 和 where区别表格举的例子)
|