V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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
Aresxue
V2EX  ›  MySQL

mysql 为什么不推荐三张表以上的关联?

  •  
  •   Aresxue · 2019-07-05 15:33:25 +08:00 · 14087 次点击
    这是一个创建于 1997 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天看到了一个说法说 mysql 不推荐三张表以上的关联,我觉得多表关联虽然可读性较差和耦合性较高,但是可以节省 IO 次数,减少执行时间从而提升接口的性能。

    68 条回复    2019-07-08 23:06:59 +08:00
    lihongjie0209
        1
    lihongjie0209  
       2019-07-05 15:36:12 +08:00
    不好扩展
    liukaining
        2
    liukaining  
       2019-07-05 15:41:53 +08:00
    谈 SQL 的性能,请拿 explain 说话

    不论是几个表,什么 sql,先 show index 看看索引怎么建的,再 explain 分析一波索引命中情况怎样
    alpha2016
        3
    alpha2016  
       2019-07-05 15:44:56 +08:00
    如果条件限制宽泛的话,三张表关联产生的笛卡儿积非常庞大,缓存机制什么的可能扛不住啊,得用 explain 来分析一下了
    nekoneko
        4
    nekoneko  
       2019-07-05 15:48:18 +08:00   ❤️ 1
    A 表一亿条,B 表一亿条,C 表一亿条,cross join 一下,完犊子了
    qwerthhusn
        5
    qwerthhusn  
       2019-07-05 15:51:49 +08:00
    主要看索引,如果都是拿着外键去连的话,10 张表 join 也很快
    virus94
        6
    virus94  
       2019-07-05 15:53:23 +08:00
    表大的话 服务器直接 GG
    Aresxue
        7
    Aresxue  
    OP
       2019-07-05 16:10:00 +08:00
    @lihongjie0209 这个我是同意的,但这个是要结合业务具体看待了,我其实是想问技术角度的。
    jswh
        8
    jswh  
       2019-07-05 16:10:15 +08:00   ❤️ 3
    不推荐的意思是这样做虽然不一定是最优的,但大概率可以避免一些前人犯过的错误。如果非常确定这样做没有问题,甚至更好,又有何不可。
    Aresxue
        9
    Aresxue  
    OP
       2019-07-05 16:11:23 +08:00
    @liukaining 不全是性能,不考虑分库分表分片的情况下,你单表可以用的 sql 一般在连接里也能用到。
    Aresxue
        10
    Aresxue  
    OP
       2019-07-05 16:12:42 +08:00
    @liukaining 上面手抖了,说的是索引
    Aresxue
        11
    Aresxue  
    OP
       2019-07-05 16:14:48 +08:00
    @alpha2016 这个大致数量级有没有,就以普通机器 4G 双核来考虑
    Immortal
        12
    Immortal  
       2019-07-05 16:15:08 +08:00
    同意 8l
    并不是说 3 张表联查一定不行 全部查询全部走在索引上 性能不会差
    只是大家 sql 能力参次不齐 还是硬性规定来预防这些 毕竟如果某个大表全表查 服务器还是很容易 gg 的

    还有一个我觉得就是"如果情况过于复杂,是不是哪里出了问题"
    如果需要三表联查,考虑下是不是表结构设计的不够合理?
    x7395759
        13
    x7395759  
       2019-07-05 16:15:19 +08:00
    也不推荐使用手机注册大于三个服务,收到垃圾短信的概率飙升 300%
    Aresxue
        14
    Aresxue  
    OP
       2019-07-05 16:15:27 +08:00
    @nekoneko 你这种太极端了,单表数据量那么多早拆了
    Aresxue
        15
    Aresxue  
    OP
       2019-07-05 16:17:24 +08:00
    @qwerthhusn 这个有点太理想化了,实际中表一多总有哪个是用不到索引的。
    Aresxue
        16
    Aresxue  
    OP
       2019-07-05 16:20:43 +08:00
    @virus94 很多系统到死可能都没那个数据量,而且这种情况你单表都没法完全避免。
    Aresxue
        17
    Aresxue  
    OP
       2019-07-05 16:22:47 +08:00
    @Immortal 我这边做电信业务的,业务复杂度比较高,这种业务系统里三表甚至更多联查实在太常见了。
    npe
        18
    npe  
       2019-07-05 16:23:02 +08:00 via Android
    拆成单条,在代码里合并
    Aresxue
        19
    Aresxue  
    OP
       2019-07-05 16:24:44 +08:00
    @jswh 道理也懂,但不考虑扩展的话一般单条 sql 一次性查出来能稍微快上一点,这个可能是我关注点有点偏了。
    jswh
        20
    jswh  
       2019-07-05 16:36:21 +08:00
    @Aresxue 你也说了不考虑扩展嘛,这个就是个权衡的事情。
    niubee1
        21
    niubee1  
       2019-07-05 16:36:43 +08:00
    主要因为那个时候 MySQL 弱得一逼
    auto
        22
    auto  
       2019-07-05 16:37:55 +08:00
    数据量大了以后若是要分库很麻烦。还有最重要的就是性能问题了。可以看这个 https://www.zhihu.com/question/56236190 里面的说明
    auto
        23
    auto  
       2019-07-05 16:47:24 +08:00
    还有可读性也是个问题,看到以前的老项目几百行的 sql,简直脑壳痛
    Takamine
        24
    Takamine  
       2019-07-05 17:28:31 +08:00
    我们是直接要求尽量把有多表关联的业务丢到内存中去处理。:doge:
    icegreen
        25
    icegreen  
       2019-07-05 17:51:48 +08:00
    可扩展性和可读性吧;
    我更看重可读性; 代码首先是给人读的。
    msg7086
        26
    msg7086  
       2019-07-05 17:54:44 +08:00 via Android
    是从哪里看出节约 io 次数的?感觉没什么区别啊……
    cnail
        27
    cnail  
       2019-07-05 17:59:40 +08:00
    因为对 hash join 支持的不好,这就是和 oracle 最大的差别
    wysnylc
        28
    wysnylc  
       2019-07-05 18:48:23 +08:00   ❤️ 1
    我连两张都不推荐
    l00t
        29
    l00t  
       2019-07-05 18:57:37 +08:00
    因为 MySQL 是个弱鸡啊,你看 Oracle 就没这说法。
    Cbdy
        30
    Cbdy  
       2019-07-05 18:58:49 +08:00 via Android
    不要脱离执行计划谈 SQL 性能
    shakoon
        31
    shakoon  
       2019-07-05 19:23:30 +08:00
    其实关联表的数量并不是决定性能的唯一要素,关联字段之间的索引配置、过滤条件的设置都比表的数量重要。在鄙人所在银行业,关联十几个表那都不是什么罕见事 - -#
    akira
        32
    akira  
       2019-07-05 20:08:12 +08:00
    别说 3 表了 2 表都是能不连就不连
    1iuh
        33
    1iuh  
       2019-07-05 20:12:03 +08:00
    我现在为了减少联表查询,在很表内冗余了很多数据。现在存储空间比较不值钱。
    jry
        34
    jry  
       2019-07-05 20:21:55 +08:00 via iPhone
    尽量 foreach
    sun1991
        35
    sun1991  
       2019-07-05 20:33:58 +08:00
    又见我手写的 foreach 比数据库引擎强... ( ̄▽ ̄)"
    说起来, MySQL 真的这么弱吗?
    sampeng
        36
    sampeng  
       2019-07-05 20:48:04 +08:00
    迪卡集。。。。
    10*10*10 就是 1000 条记录。。
    sampeng
        37
    sampeng  
       2019-07-05 20:51:42 +08:00   ❤️ 2
    前几天还和别人掰扯关联表太多的问题。。。查询速度还可以吧。几十毫秒。但是。数据库 cpu 高的感人。。差不多最高峰 50%吧。。然后优化掉这一个关联了 5 张表的 sql。
    前面说索引的。索引也不是银弹啊。5 张表。explain 全部走索引。4 张索引查询 100 条记录以下,1 条索引需要扫描 10000 左右的数据集。大部分 dba 都会说这个 explain 已经没得优化了。。。
    然后我就和人家掰扯。。把那个扫描 10000 的拿出来。然后再查后面的 4 个表连表。。恩。CPU 掉到 5%。。。
    wc951
        38
    wc951  
       2019-07-05 21:14:48 +08:00
    单表查询我为什么不用 hbase、hive、impala
    hhyvs111
        39
    hhyvs111  
       2019-07-05 22:07:02 +08:00
    大公司都是存一张表,省事
    des
        40
    des  
       2019-07-05 22:35:10 +08:00 via Android
    实际环境真有那么多表 join,而且还都是 cross join ?
    就算是只用一个表,也照样能能整崩,老老实实多学数据库和优化才是正道
    realpg
        41
    realpg  
       2019-07-05 22:43:51 +08:00
    MYSQL 不推荐技术渣的人三张表以上关联
    reus
        42
    reus  
       2019-07-06 00:28:29 +08:00   ❤️ 4
    MySQL 5 对于 join 只有 nested loop 一种计划,没有 hash join,没有 merge join,所以你再怎么优化,残疾就是残疾,于是各位就得出了“少 join ”的结论。

    你用 Oracle,PostgreSQL,SQL Server 这些数据库,就完全没有这些问题。
    bzj
        43
    bzj  
       2019-07-06 00:39:55 +08:00
    没有用过 3 张表以上关联的估计都没做过什么复杂的系统,比如一个简单的订单数据列表,起码要关联 5 张表
    bzj
        44
    bzj  
       2019-07-06 00:41:00 +08:00
    @sun1991 能说出手写 foreach 的,应该是 phper
    huijiewei
        45
    huijiewei  
       2019-07-06 08:38:39 +08:00 via iPhone
    说关联五张表的都是做并发 1 的系统的吧
    Aresxue
        46
    Aresxue  
    OP
       2019-07-06 09:14:40 +08:00
    @msg7086 访问数据库的次数
    xuanbg
        47
    xuanbg  
       2019-07-06 09:14:41 +08:00
    @nekoneko 你没任何条件的话,单表读 1 亿照样完犊子。如果有条件的话,1 亿里面取 100 条数据,关联、条件都有索引,3 个表 join 写对 sql 也是几十毫秒的事情。
    Aresxue
        48
    Aresxue  
    OP
       2019-07-06 09:17:19 +08:00
    @wysnylc 如果是很看重接口响应速度的业务,单表和关联的效率能查 10 倍以上,当然是在数据量远没有达到机器性能瓶颈的时候
    Aresxue
        49
    Aresxue  
    OP
       2019-07-06 09:19:28 +08:00
    @Cbdy 也不单单是性能,还是如何去权衡的问题,大概的度是多少,就好比 mysql 单表 500 万性能就会有问题,这个说法虽然不对但也有一定的借鉴意义
    Aresxue
        50
    Aresxue  
    OP
       2019-07-06 09:20:25 +08:00
    @shakoon 传统行业里比较重 DB 轻业务,以前用 Oracle 的时候见过几千行的 sql。。。
    Aresxue
        51
    Aresxue  
    OP
       2019-07-06 09:22:26 +08:00
    @sampeng 笛卡尔积不是这么算的,在连接查询里,如果 on 条件是非唯一字段,会出现笛卡尔积(局部笛卡尔积);如果 on 条件是表的唯一字段,则不会出现笛卡尔积。
    Aresxue
        52
    Aresxue  
    OP
       2019-07-06 09:27:57 +08:00
    @sampeng 扯到现在你这个算是唯一一个比较有建设性的说法了,数据库 CPU 这块有什么好的资料吗?会卡死是真的,见过卡死的,顺便问下一般 4G 双核的机器能支持 mysql 多大的计算量而不影响总体性能?
    Aresxue
        53
    Aresxue  
    OP
       2019-07-06 09:32:44 +08:00
    @huijiewei 传统行业里这种关联很多,除非是互联网而且是对高并发要求很高的,不然 5 张表完全是小 case,如果把定时任务也能算的吧,那这个可就多了。。。
    mikulch
        54
    mikulch  
       2019-07-06 09:38:35 +08:00
    1. mysql 就是为高并发设计的,单表高并发随便查都不会有太大的性能问题。
    2. mysql 不怕单表高并发查询,不代表不怕关联查询。mysql 的设计比较怕联表查询,特别是复杂的业务联表查询+查询里面的计算。
    3. 在 sql 里面实现复杂的业务和联表,是比较偏向于传统 it 的做法。
    huijiewei
        55
    huijiewei  
       2019-07-06 10:11:47 +08:00 via iPhone
    @Aresxue 关联多只是 db 的习惯而已,不想拥抱变化的继续关联呗,反正我写存储过程写的已经吐过了
    sampeng
        56
    sampeng  
       2019-07-06 12:20:04 +08:00 via iPhone
    @Aresxue 没有…纯看官方手册加搜索。如果所有 on the 条件都是唯一键那就好了咯。但通常 n 表 join 是不可能出现这种情况的。

    就你这小水管配置?别指望优化了…先加机器吧…量大 4 核 32g 没毛病。量小也要 2 核 16g 也行吧。我是选择内存大,cpu 小的配置。几乎全在缓存里。没有 io 操作
    sampeng
        57
    sampeng  
       2019-07-06 12:24:41 +08:00 via iPhone
    @Aresxue 2c4M 没有高并发…这配置就是做实验用用还行。量大点就要跪…
    qiyuey
        58
    qiyuey  
       2019-07-06 12:43:17 +08:00 via Android
    我一般不推荐关联
    Aresxue
        59
    Aresxue  
    OP
       2019-07-06 13:18:58 +08:00
    @huijiewei 互联网的趋势是重业务轻 DB,但是关联这种东西我觉得现阶段还是很有必要的。还有扯存储过程干嘛,Mysql 的存储过程本来就是个半成品,用的人又不多。
    Aresxue
        60
    Aresxue  
    OP
       2019-07-06 13:21:18 +08:00
    @sampeng 只是举个例子,比较小块的机器容易量化一点,我这边项目生产用的都是 16 核 256G 的。。。但是这种机器你知道有多贵吗。。。
    sampeng
        61
    sampeng  
       2019-07-06 13:57:13 +08:00 via iPhone
    @Aresxue 土豪…
    cnzjl
        62
    cnzjl  
       2019-07-06 13:57:51 +08:00
    目前我就碰到了这个问题,一个 sql 关联了三张表,目前 limit 10 条数据是 20-30s,数据量很大,现在想到解决办法就是抽出结果表..。
    sarices
        63
    sarices  
       2019-07-06 14:02:29 +08:00
    mysql 还好吧,税务局的系统 oracle 常常 4~5 张表关联,还是 dblink,跨网络,看到这种真的痛不欲生
    autogen
        64
    autogen  
       2019-07-07 01:28:01 +08:00
    10 几张表关联都遇到过。。。不过是离线统计数据的时候,线上表越少越好
    dong648629778
        65
    dong648629778  
       2019-07-07 08:10:30 +08:00 via iPhone
    现在都不允许两张表关联了好吗。。
    applehater
        66
    applehater  
       2019-07-08 00:59:47 +08:00
    @wysnylc 那用关系数据库干嘛
    @dong648629778
    Aresxue
        67
    Aresxue  
    OP
       2019-07-08 08:57:26 +08:00
    @dong648629778 不准两张表关联那就该直接上 Nosql 了,除非是你们技术管理者在偷懒,当然不同的 Nosql 实际应用中也会有很多问题,没有实际经验的话一般也很难搞定
    pathbox
        68
    pathbox  
       2019-07-08 23:06:59 +08:00 via iPhone
    io 次数多和 io 长时间执行相比 长时间往往会导致更严重的问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3588 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 04:53 · PVG 12:53 · LAX 20:53 · JFK 23:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.