› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
liunaijie
V2EX  ›  MySQL

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

  •  
  •   liunaijie · Oct 14, 2019 · 8051 views
    This topic created in 2539 days ago, the information mentioned may be changed or developed.

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

    17 replies  •  2019-10-15 09:06:13 +08:00
    clarkyi
        1
    clarkyi  
       Oct 14, 2019
    explain 一下你就知道了
    lihongjie0209
        2
    lihongjie0209  
       Oct 14, 2019
    select b.score from a,b 这是笛卡尔积, 要爆炸的。
    F281M6Dh8DXpD1g2
        3
    F281M6Dh8DXpD1g2  
       Oct 14, 2019   ❤️ 1
    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
        4
    reus  
       Oct 14, 2019
    首先学会用 explain,然后你就能自己分析,不需要问人了。
    qwerthhusn
        5
    qwerthhusn  
       Oct 14, 2019
    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
        6
    newtype0092  
       Oct 14, 2019
    什么情况下都应该使用 join,from a,b 这种是满足特定条件的简便写法,你不知道原本含义的话就不要使用简便写法防止踩坑。
    inner join 的问题在于如果学生没有成绩结果里是没有这行的,如果有 3 个张三,某个没有成绩,你这个结果只会返回 2 行(假设 1 个学生最多只有 1 个成绩的情况下)
    left join 能保证左表数据是完整的
    wangyzj
        7
    wangyzj  
       Oct 14, 2019
    永远用 join
    用笛卡尔积会炸
    4everYang
        8
    4everYang  
       Oct 14, 2019
    第一个 sql 是 a*b 行数的临时表再 where
    第二个 sql 是 on 后的临时表再 where
    zhuyichen1017
        9
    zhuyichen1017  
       Oct 14, 2019
    我觉得 Mysql 的优化器应该不会去做笛卡尔积吧
    Aresxue
        10
    Aresxue  
       Oct 14, 2019
    扫描行数的区别,看下执行计划
    x66
        11
    x66  
       Oct 14, 2019
    MySQL 8.0 实测并不会生成笛卡尔积。。
    从 explain 上来看也并没有什么区别。。
    huijiewei
        12
    huijiewei  
       Oct 14, 2019
    这两种实现的数据结果完全是不一样的。所以没有性能区别
    huijiewei
        13
    huijiewei  
       Oct 14, 2019
    up 我看到了 a 表的限定,所以没有区别,没有 A 表限定的话就有区别了
    sadfQED2
        14
    sadfQED2  
       Oct 14, 2019 via Android
    @x66 MySql5.7 实测也没生成笛卡尔积,而且 explain 也没有什么区别
    Reso1mi
        15
    Reso1mi  
       Oct 14, 2019
    如果第一句写成 inner join on 的话,可能性能会好一点,查询优化器可以选择查询成本较小的连接循序🙄
    NotFoundEgg
        16
    NotFoundEgg  
       Oct 14, 2019
    个人认为在像你例子中这种简单的 sql 两者是等价的,但是在以后的实际工作中多表联查使用你第一种写法会爆炸的,所以养成好习惯,能 left join 的请一律 left join
    liouop
        17
    liouop  
       Oct 15, 2019 via Android
    select from 两张表 是隐式调用 inner join,直接产生笛卡尔积。具体可以看一下 mysql 必知必会,查一下隐式与显式的区别。主要区别在于前面有人讲到的,on 与 where,on 会先筛选再连接,where 也是连接再条件判断
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   884 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 19:49 · PVG 03:49 · LAX 12:49 · JFK 15:49
    ♥ Do have faith in what you're doing.