要是不准 Join,如何解决某些需要 Join 后查询的问题?

2018-07-26 13:01:56 +08:00
 abcbuzhiming
看不少经验分享提到 Mysql 在大数据量,大并发下,尽量不要用 Join,阿里巴巴的规范里提出 3 表以上别 Join ; 58 更激进直接禁止了 Join,但是 58 有自己的索引服务可以进行检索,我就想那些没有索引服务的,怎么解决某些必须 Join 后搜索的问题,用冗余字段,且不说冗余字段有关联更新问题;你要加多少冗余字段呢,那主表不是又变大了吗,另外 1 对 1 关系加冗余字段可行,多对多关系加冗余字段是没效的啊,有没有有人有这方面的经验?
12241 次点击
所在节点    MySQL
41 条回复
abcbuzhiming
2018-07-26 15:18:04 +08:00
@kran 所以你怎么做?把这十几个字段全往主表里加吗?你这表膨胀成啥样了?关联更新还麻烦的要死
liprais
2018-07-26 15:18:13 +08:00
看了半天原来 lz 是抬杠来了
要不要禁止 join 看应用呗
oltp 和 olap 是完全不同的应用,不可一概而论的
galaxyyao
2018-07-26 15:18:23 +08:00
有用到分库分表,基本大多数情况都有数据仓库层或 ODS,用于聚合数据。可以通过中间件,做到应用无感。
TommyLemon
2018-07-26 15:19:24 +08:00
大公司有实力在 应用层 优化地比 Inno DB 等 MySQL 引擎好,没这个实力还是用 JOIN 吧,
不然 IN 后面几千几万的 id 照样性能差,甚至可能导致缓冲区溢出。
feverzsj
2018-07-26 15:23:15 +08:00
需要用 join 的就用,你自己的解决方案不可能比数据库内的好,而且中间层难以实现理想的事务性
abcbuzhiming
2018-07-26 15:34:44 +08:00
@liprais 我没抬杠,但是我要找到能够解决在禁用 join 下的搜索办法
est
2018-07-26 15:34:50 +08:00
不管什么办法,禁止 JOIN,那就数据冗余提前 JOIN 好物化呗。空间换时间而已。
huijiewei
2018-07-26 15:34:57 +08:00
写过五年存储过程的路过

近几年基本不手写 SQL,现在,基本和 JOIN 再见了

如果你觉得摆脱不了 JOIN 那就用

但是跑过来说没 JOIN 就搞不了什么的,除了说你菜还能夸你杠?
janxin
2018-07-26 15:36:38 +08:00
lz 先看应用场景,那个是 join 限制还是受限于高并发的应用场景的效率提升

没有这种限制,怎么搞都无所谓,最多就是等着就好
letitbesqzr
2018-07-26 15:44:42 +08:00
看使用场景的,企业级开发里,动不动上千张表,要展现一个表格,要让你从十多个表里关联处理,这种情况不用 join 折腾死你。

互联网业务,要求高迸发情况下,在设计的时候就考虑好数据沉淀,尽量就不要去使用 join,对分库分表也更友好。
xomix
2018-07-26 16:04:56 +08:00
如果非要多表联合查询可用中间临时表,按照你说的班级对应学号再对应学生信息的例子来说吧。
第一步用班级表找到学号集合写入临时表,第二部用学号集合临时表 join 学生表查到学生 id 集合写到临时表,最后用学生 id 集合查找学生信息,生成需要的输出表。

这样比三次 join 会快很多,为什么自己看查询分析器。
saulshao
2018-07-26 17:15:27 +08:00
我其实也有类似于楼主的困惑。
按照数据库设计的原则,应该是表越多越好。
如果真的不让 JOIN,对于中间层编码的负担其实是蛮大的。我能想到的办法就是 @xomix 的回帖,只是不用临时表,直接读到内存里,分批循环.......但是我觉得这其实很难保证可靠。所以其实临时表是更快更好的办法。
zjsxwc
2018-07-26 17:24:11 +08:00
加冗余字段

使用应用层代码多次查询


编不下去了,表多了用 join 不是很正常的需求吗?笛卡尔积的导致效率问题,不可避免,解决方案无非是内存空间换时间
rockyou12
2018-07-26 18:02:49 +08:00
不 join 其实还挺正常的……真的业务量大了基本瓶颈都在数据库,然后数据库扩容又特别麻烦,但是缓存却比较容易。你都是手写 sql,然后一堆 join,怎么搞应用层的缓存?
mandy0119
2018-07-26 19:24:50 +08:00
很简单的问题啊。按你举得例子,先应用层查一下班级表,把复合要求的学生 id 存一个 list,再将 list 的数据遍历逐个查学生表就行了。我们这边从来不怕应用层繁琐,互联网项目把压力拦截在应用层,通过内存进行优化,打死不透到数据库是常识吧。
CRVV
2018-07-26 20:15:25 +08:00
这根本不是 JOIN 的问题

按照关系型数据库的范式来设计表,不加缓存,JOIN 必然是最快的方法
如果有其它的方法比 JOIN 快,那是数据库太蠢了

如果用这种方式还不够快,那解决的方法当然多得很
比如你可以不用关系型数据库

另外,这类问题的重点是不要把代价大的事情放到关系型数据库里去做。
不用 JOIN 的 SQL 可以代价很大,JOIN 100 个表也可以代价很小。
阿里巴巴规定 3 个表不能 JOIN,这说明他家工程师水平比较烂,没有能力判断一个 SQL 的代价是不是太大,适不适合放到数据库去查询,仅此而已。
Infernalzero
2018-07-26 22:02:16 +08:00
冗余字段是一种方式,牺牲些一致性
还有种方式就是通过数据同步创建新的宽表来查询,这里可以接搜索,也可以直接查
bringyou
2018-07-26 23:48:31 +08:00
跟一个前阿里云的哥们聊过,听说他们是不让用 join 的,统一上 opensearch.
但是对普通公司来说所有表都上 opensearch 成本难以接受吧
ryuzaki113
2018-07-27 09:30:54 +08:00
不做统计还是别 join 了
glacer
2018-08-04 00:52:59 +08:00
强制规定 JOIN 表的数量也只是部分大公司出台的规定,这也是他们的无奈之举,在开发水平参差不齐的情况下这是保证系统鲁棒性最有效的办法。并不是说多表 JOIN 一定会造成性能问题,只要索引得当,多表 JOIN 一样很快,这本身就是关系型数据库的优势所在。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/474328

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX