⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 dwz.cn/LuowUpuc 「知乎」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

最近,在知乎上看到一个有意思的问题,我个人觉得不错,挺有收获,在这里跟大家分享一下。

题目:《阿里巴巴JAVA开发手册》里面写超过三张表禁止join 这是为什么?这样的话那sql要怎么写?

一般,我对于这种问题,解决方案是查询官方文档,要么查看我的工具书《高性能的MySQL》,在本书的6.3节:重构查询的方式里面提到,需要考虑实际情况,看看是否有必要将一个复杂的查询分解成多个简单的查询,并不一定要把所有的工作全都移交给数据库(转换思路)!!!

其实Join拆解的核心就是利用In关键字,这个也是出自该书,你不信,那我还是只能给你拍照(见下图)。

所有的问题答案都在书中,这也是我经常推荐大家,要多读书,读好书,比如,我经常给你们推荐的书(我又在装叉了,哈哈)。

计算机解决问题,要么用空间换时间,要么用时间换空间,此二法基本上能解决大多数疑难杂症,你现在看到的各种高大上的玩法,基本上都跟此二法沾亲带故。

比如,该问题下,阿里大佬李晨曦的回答,通过空间换时间的方案来设计表,虽然数据冗余了,但查询性能显著提升了,挺有意思。


该大佬的回答如下:

一:为什么做这种限制?

打个比方,如果我有无限的钱,我想买个豪华别墅,想买个跑车,想买个直升飞机,但现实是我没钱,只能租房住,只能走路上下班。

如果数据库的性能无限强大,多个表的join肯定是需要的,尤其是复杂的分析型(OLAP)查询,甚至可能涉及10几个表的join,但现实是大部分数据库的性能都太弱了,尤其是涉及到多表join的查询。给@韩飞点个赞,国内懂这个做这个的太少了,以后就靠他们了。

规范一看就是在使用MySQL时的限制(这种规范实际上迫不得已的限制),做这个限制有两个原因:一是优化器很弱,涉及多个表的查询,往往得不到很好的查询计划,这块比较复杂,感兴趣的朋友可以关注我,我以后会写文章专门介绍;二是执行器很弱,只有nested loop join,block nested loop join和index nested loop join。

1、nested loop join就是分别从两个表读一行数据进行两两对比,复杂度是n^2。

2、block nested loop join是分别从两个表读很多行数据,然后进行两两对比,复杂度也是n^2,只是少了些函数调用等overhead。

3、index nested loop join是从第一个表读一行,然后在第二个表的索引中查找这个数据,索引是B+树索引,复杂度可以近似认为是nlogn,比上面两个好很多,这就是要保证关联字段有索引的原因。

4、 如果有hash join,就不用做这种限制了,用第一个表(小表)建hash table,第二个表在hash table中查找匹配的项,复杂度是n。缺点是hash table占的内存可能会比较大,不过也有基于磁盘的hash join,实现起来比较复杂。

二:在这种限制下SQL怎么写?

可是我确实需要两个表里的数据链接在一起啊,我们可以做个冗余,建表的时候,就把这些列放在一个表里,比如一开始有student(id, name),class(id, description),student_class(student_id, class_id)三张表,这样是符合数据库范式的(第一范式,第二范式,第三范式,BC范式等),没有任何冗余,但是马上就不符合“编程规范“了,那我们可以用一张大表代替它,student_class_full(student_id, class_id, name, description),这样name和description可能要被存储多份,但是由于不需要join了,查询的性能就可以提高很多了。

任何的规范都是在特定情况下的某种妥协,脱离了这个环境,就不一定成立了。


其实,很多同学问我,我是如何解决编程的问题?其实我就是按照以前做数学应用题的方法来解决编程问题,大问题拆分成小问题,小问题在书中就会有相应的例题,照猫画虎,所有小问题都击破了,那么,大问题就迎刃而解了,这便是所谓的不攻自破。

其实,你遇到的问题,90%都能通过搜索引擎解决,而你非得要做伸手党,哎...

最后,还是推荐一下《高性能MySQL》这本给各位同学(这是我第3次推荐了~~~),没事多读读,网上也有电子版,但我建议大家还是去买一本实体书,当做工具书用。

文章目录
  1. 1. 一:为什么做这种限制?
  2. 2. 二:在这种限制下SQL怎么写?