这两种查询的实现,有什么区别?什么场景下使用 join? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
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 7631 views
    This topic created in 2387 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 也没有什么区别
    Shaw314
        15
    Shaw314  
       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     Solana     3215 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 84ms UTC 14:08 PVG 22:08 LAX 07:08 JFK 10:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86