有这么两张表
学生表 a
(id,name)
成绩表 b
(id,a_id,score)
然后查询张三的成绩。
我之前都是用:
select b.score from a,b where a.name = '张三' and a.id = b.a_id
这两天面试的时候一个面试官问我,这个用 join 怎么写。
select b.score from b left join a on a.id = b.a_id where a.name = '张三'
请问一下,这两种实现在性能上有什么区别吗?我一般不会去用 join 写,什么场景下要用 join 这么写?
1
clarkyi 2019-10-14 11:25:38 +08:00
explain 一下你就知道了
|
2
lihongjie0209 2019-10-14 11:26:04 +08:00
select b.score from a,b 这是笛卡尔积, 要爆炸的。
|
3
liprais 2019-10-14 11:41:20 +08:00 1
|
4
reus 2019-10-14 11:46:20 +08:00
首先学会用 explain,然后你就能自己分析,不需要问人了。
|
5
qwerthhusn 2019-10-14 11:47:36 +08:00
from a join b on a.c = b.d 这个是内连接和 inner join 是一样的效果
from a join b on a.c = b.d(+) 这个是左连接还是右连接忘记了,MySQL 不支持(+)连接符,Oracle 是支持的,但是一般都是推荐用 left|right join...on...这种,因为(+)有点不好理解 @lihongjie0209 where 条件会限制不是笛卡尔集的 |
6
newtype0092 2019-10-14 11:59:59 +08:00
什么情况下都应该使用 join,from a,b 这种是满足特定条件的简便写法,你不知道原本含义的话就不要使用简便写法防止踩坑。
inner join 的问题在于如果学生没有成绩结果里是没有这行的,如果有 3 个张三,某个没有成绩,你这个结果只会返回 2 行(假设 1 个学生最多只有 1 个成绩的情况下) left join 能保证左表数据是完整的 |
7
wangyzj 2019-10-14 12:04:11 +08:00
永远用 join
用笛卡尔积会炸 |
8
zsy979 2019-10-14 13:34:33 +08:00
第一个 sql 是 a*b 行数的临时表再 where
第二个 sql 是 on 后的临时表再 where |
9
zhuyichen1017 2019-10-14 14:01:51 +08:00
我觉得 Mysql 的优化器应该不会去做笛卡尔积吧
|
10
Aresxue 2019-10-14 15:26:51 +08:00
扫描行数的区别,看下执行计划
|
11
x66 2019-10-14 15:51:18 +08:00
MySQL 8.0 实测并不会生成笛卡尔积。。
从 explain 上来看也并没有什么区别。。 |
12
huijiewei 2019-10-14 15:54:15 +08:00
这两种实现的数据结果完全是不一样的。所以没有性能区别
|
13
huijiewei 2019-10-14 15:55:37 +08:00
up 我看到了 a 表的限定,所以没有区别,没有 A 表限定的话就有区别了
|
15
Shaw314 2019-10-14 16:28:34 +08:00
如果第一句写成 inner join on 的话,可能性能会好一点,查询优化器可以选择查询成本较小的连接循序🙄
|
16
NotFoundEgg 2019-10-14 16:59:31 +08:00
个人认为在像你例子中这种简单的 sql 两者是等价的,但是在以后的实际工作中多表联查使用你第一种写法会爆炸的,所以养成好习惯,能 left join 的请一律 left join
|
17
liouop 2019-10-15 09:06:13 +08:00 via Android
select from 两张表 是隐式调用 inner join,直接产生笛卡尔积。具体可以看一下 mysql 必知必会,查一下隐式与显式的区别。主要区别在于前面有人讲到的,on 与 where,on 会先筛选再连接,where 也是连接再条件判断
|