这两种查询的实现,有什么区别?什么场景下使用 join?

2019-10-14 11:23:51 +08:00
 liunaijie

有这么两张表
学生表 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 这么写?

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/609084

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX