今天看到了一个说法说 mysql 不推荐三张表以上的关联,我觉得多表关联虽然可读性较差和耦合性较高,但是可以节省 IO 次数,减少执行时间从而提升接口的性能。
1 lihongjie0209 2019-07-05 15:36:12 +08:00 不好扩展 |
![]() | 2 liukaining 2019-07-05 15:41:53 +08:00 谈 SQL 的性能,请拿 explain 说话 不论是几个表,什么 sql,先 show index 看看索引怎么建的,再 explain 分析一波索引命中情况怎样 |
![]() | 3 alpha2016 2019-07-05 15:44:56 +08:00 如果条件限制宽泛的话,三张表关联产生的笛卡儿积非常庞大,缓存机制什么的可能扛不住啊,得用 explain 来分析一下了 |
![]() | 4 nekoneko 2019-07-05 15:48:18 +08:00 ![]() A 表一亿条,B 表一亿条,C 表一亿条,cross join 一下,完犊子了 |
![]() | 5 qwerthhusn 2019-07-05 15:51:49 +08:00 主要看索引,如果都是拿着外键去连的话,10 张表 join 也很快 |
![]() | 6 virus94 2019-07-05 15:53:23 +08:00 表大的话 服务器直接 GG |
![]() | 7 Aresxue OP @lihongjie0209 这个我是同意的,但这个是要结合业务具体看待了,我其实是想问技术角度的。 |
![]() | 8 jswh 2019-07-05 16:10:15 +08:00 ![]() 不推荐的意思是这样做虽然不一定是最优的,但大概率可以避免一些前人犯过的错误。如果非常确定这样做没有问题,甚至更好,又有何不可。 |
![]() | 9 Aresxue OP @liukaining 不全是性能,不考虑分库分表分片的情况下,你单表可以用的 sql 一般在连接里也能用到。 |
![]() | 10 Aresxue OP @liukaining 上面手抖了,说的是索引 |
![]() | 12 Immortal 2019-07-05 16:15:08 +08:00 同意 8l 并不是说 3 张表联查一定不行 全部查询全部走在索引上 性能不会差 只是大家 sql 能力参不齐 还是硬性规定来预防这些 毕竟如果某个大表全表查 服务器还是很容易 gg 的 还有一个我觉得就是"如果情况过于复杂,是不是哪里出了问题" 如果需要三表联查,考虑下是不是表结构设计的不够合理? |
![]() | 13 quickma 2019-07-05 16:15:19 +08:00 也不推荐使用手机注册大于三个服务,收到垃圾短信的概率飙升 300% |
![]() | 15 Aresxue OP @qwerthhusn 这个有点太理想化了,实际中表一多总有哪个是用不到索引的。 |
![]() | 18 npe 2019-07-05 16:23:02 +08:00 via Android 拆成单条,在代码里合并 |
![]() | 21 niubee1 2019-07-05 16:36:43 +08:00 主要因为那个时候 MySQL 弱得一逼 |
22 auto 2019-07-05 16:37:55 +08:00 数据量大了以后若是要分库很麻烦。还有最重要的就是性能问题了。可以看这个 https://www.zhihu.com/question/56236190 里面的说明 |
23 auto 2019-07-05 16:47:24 +08:00 还有可读性也是个问题,看到以前的老项目几百行的 sql,简直脑壳痛 |
![]() | 24 Takamine 2019-07-05 17:28:31 +08:00 我们是直接要求尽量把有多表关联的业务丢到内存中去处理。:doge: |
![]() | 25 icegreen 2019-07-05 17:51:48 +08:00 可扩展性和可读性吧; 我更看重可读性; 代码首先是给人读的。 |
![]() | 26 msg7086 2019-07-05 17:54:44 +08:00 via Android 是从哪里看出节约 io 次数的?感觉没什么区别啊…… |
27 cnail 2019-07-05 17:59:40 +08:00 因为对 hash join 支持的不好,这就是和 oracle 最大的差别 |
![]() | 28 wysnylc 2019-07-05 18:48:23 +08:00 ![]() 我连两张都不推荐 |
29 l00t 2019-07-05 18:57:37 +08:00 因为 MySQL 是个弱鸡啊,你看 Oracle 就没这说法。 |
30 Cbdy 2019-07-05 18:58:49 +08:00 via Android 不要脱离执行计划谈 SQL 性能 |
![]() | 31 shakoon 2019-07-05 19:23:30 +08:00 其实关联表的数量并不是决定性能的唯一要素,关联字段之间的索引配置、过滤条件的设置都比表的数量重要。在鄙人所在银行业,关联十几个表那都不是什么罕见事 - -# |
![]() | 32 akira 2019-07-05 20:08:12 +08:00 别说 3 表了 2 表都是能不连就不连 |
![]() | 33 1iuh 2019-07-05 20:12:03 +08:00 我现在为了减少联表查询,在很表内冗余了很多数据。现在存储空间比较不值钱。 |
![]() | 34 jry 2019-07-05 20:21:55 +08:00 via iPhone 尽量 foreach |
![]() | 35 sun1991 2019-07-05 20:33:58 +08:00 又见我手写的 foreach 比数据库引擎强... ( ̄ ̄)" 说起来, MySQL 真的这么弱吗? |
36 sampeng 2019-07-05 20:48:04 +08:00 迪卡集。。。。 10*10*10 就是 1000 条记录。。 |
37 sampeng 2019-07-05 20:51:42 +08:00 ![]() 前几天还和别人掰扯关联表太多的问题。。。查询速度还可以吧。几十毫秒。但是。数据库 cpu 高的感人。。差不多最高峰 50%吧。。然后优化掉这一个关联了 5 张表的 sql。 前面说索引的。索引也不是银弹啊。5 张表。explain 全部走索引。4 张索引查询 100 条记录以下,1 条索引需要扫描 10000 左右的数据集。大部分 dba 都会说这个 explain 已经没得优化了。。。 然后我就和人家掰扯。。把那个扫描 10000 的拿出来。然后再查后面的 4 个表连表。。恩。CPU 掉到 5%。。。 |
38 wc951 2019-07-05 21:14:48 +08:00 单表查询我为什么不用 hbase、hive、impala |
![]() | 39 hhyvs111 2019-07-05 22:07:02 +08:00 大公司都是存一张表,省事 |
![]() | 40 des 2019-07-05 22:35:10 +08:00 via Android 实际环境真有那么多表 join,而且还都是 cross join ? 就算是只用一个表,也照样能能整崩,老老实实多学数据库和优化才是正道 |
![]() | 41 realpg PRO MYSQL 不推荐技术渣的人三张表以上关联 |
![]() | 42 reus 2019-07-06 00:28:29 +08:00 ![]() MySQL 5 对于 join 只有 nested loop 一种计划,没有 hash join,没有 merge join,所以你再怎么优化,残疾就是残疾,于是各位就得出了“少 join ”的结论。 你用 Oracle,PostgreSQL,SQL Server 这些数据库,就完全没有这些问题。 |
43 bzj 2019-07-06 00:39:55 +08:00 没有用过 3 张表以上关联的估计都没做过什么复杂的系统,比如一个简单的订单数据列表,起码要关联 5 张表 |
![]() | 45 huijiewei 2019-07-06 08:38:39 +08:00 via iPhone 说关联五张表的都是做并发 1 的系统的吧 |
![]() | 47 xuanbg 2019-07-06 09:14:41 +08:00 @nekoneko 你没任何条件的话,单表读 1 亿照样完犊子。如果有条件的话,1 亿里面取 100 条数据,关联、条件都有索引,3 个表 join 写对 sql 也是几十毫秒的事情。 |
![]() | 48 Aresxue OP @wysnylc 如果是很看重接口响应速度的业务,单表和关联的效率能查 10 倍以上,当然是在数据量远没有达到机器性能瓶颈的时候 |
![]() | 49 Aresxue OP @Cbdy 也不单单是性能,还是如何去权衡的问题,大概的度是多少,就好比 mysql 单表 500 万性能就会有问题,这个说法虽然不对但也有一定的借鉴意义 |
![]() | 51 Aresxue OP @sampeng 笛卡尔积不是这么算的,在连接查询里,如果 on 条件是非唯一字段,会出现笛卡尔积(局部笛卡尔积);如果 on 条件是表的唯一字段,则不会出现笛卡尔积。 |
![]() | 52 Aresxue OP @sampeng 扯到现在你这个算是唯一一个比较有建设性的说法了,数据库 CPU 这块有什么好的资料吗?会卡死是真的,见过卡死的,顺便问下一般 4G 双核的机器能支持 mysql 多大的计算量而不影响总体性能? |
![]() | 53 Aresxue OP @huijiewei 传统行业里这种关联很多,除非是互联网而且是对高并发要求很高的,不然 5 张表完全是小 case,如果把定时任务也能算的吧,那这个可就多了。。。 |
![]() | 54 mikulch 2019-07-06 09:38:35 +08:00 1. mysql 就是为高并发设计的,单表高并发随便查都不会有太大的性能问题。 2. mysql 不怕单表高并发查询,不代表不怕关联查询。mysql 的设计比较怕联表查询,特别是复杂的业务联表查询+查询里面的计算。 3. 在 sql 里面实现复杂的业务和联表,是比较偏向于传统 it 的做法。 |
![]() | 55 huijiewei 2019-07-06 10:11:47 +08:00 via iPhone @Aresxue 关联多只是 db 的习惯而已,不想拥抱变化的继续关联呗,反正我写存储过程写的已经吐过了 |
56 sampeng 2019-07-06 12:20:04 +08:00 via iPhone @Aresxue 没有…纯看官方手册加搜索。如果所有 on the 条件都是唯一键那就好了咯。但通常 n 表 join 是不可能出现这种情况的。 就你这小水管配置?别指望优化了…先加机器吧…量大 4 核 32g 没毛病。量小也要 2 核 16g 也行吧。我是选择内存大,cpu 小的配置。几乎全在缓存里。没有 io 操作 |
![]() | 58 qiyuey 2019-07-06 12:43:17 +08:00 via Android 我一般不推荐关联 |
![]() | 59 Aresxue OP @huijiewei 互联网的趋势是重业务轻 DB,但是关联这种东西我觉得现阶段还是很有必要的。还有扯存储过程干嘛,Mysql 的存储过程本来就是个半成品,用的人又不多。 |
![]() | 60 Aresxue OP @sampeng 只是举个例子,比较小块的机器容易量化一点,我这边项目生产用的都是 16 核 256G 的。。。但是这种机器你知道有多贵吗。。。 |
![]() | 62 cnzjl 2019-07-06 13:57:51 +08:00 目前我就碰到了这个问题,一个 sql 关联了三张表,目前 limit 10 条数据是 20-30s,数据量很大,现在想到解决办法就是抽出结果表..。 |
![]() | 63 sarices 2019-07-06 14:02:29 +08:00 mysql 还好吧,税务局的系统 oracle 常常 4~5 张表关联,还是 dblink,跨网络,看到这种真的痛不欲生 |
![]() | 64 autogen 2019-07-07 01:28:01 +08:00 10 几张表关联都遇到过。。。不过是离线统计数据的时候,线上表越少越好 |
65 dong648629778 2019-07-07 08:10:30 +08:00 via iPhone 现在都不允许两张表关联了好吗。。 |
![]() | 66 applehater 2019-07-08 00:59:47 +08:00 |
![]() | 67 Aresxue OP @dong648629778 不准两张表关联那就该直接上 Nosql 了,除非是你们技术管理者在偷懒,当然不同的 Nosql 实际应用中也会有很多问题,没有实际经验的话一般也很难搞定 |
![]() | 68 pathbox 2019-07-08 23:06:59 +08:00 via iPhone io 次数多和 io 长时间执行相比 长时间往往会导致更严重的问题 |