
有这么两张表
学生表 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 F281M6Dh8DXpD1g2 2019-10-14 11:41:20 +08:00 |
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 也是连接再条件判断 |