专栏名称: 朱小厮的博客
著有畅销书:《深入理解Kafka》和《RabbitMQ实战指南》。公众号主要用来分享Java技术栈、Golang技术栈、消息中间件(如Kafka、RabbitMQ)、存储、大数据以及通用型技术架构等相关的技术。
目录
相关文章推荐
融媒吴江  ·  《哪吒2》萌值担当!也来吴江啦! ·  昨天  
融媒吴江  ·  《哪吒2》萌值担当!也来吴江啦! ·  昨天  
天津广播  ·  刚刚 | 董明珠:找到接班人! ·  3 天前  
51好读  ›  专栏  ›  朱小厮的博客

阿里规定超过三张表禁止join,为啥?

朱小厮的博客  · 公众号  ·  · 2019-10-24 08:51

正文

点击上方“ 朱小厮的博客 ”,选择“ 设为星标

后台回复” 加群 “加入公众号专属技术群


来源: https://dwz.cn/LuowUpuc



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


题目: 《阿里巴巴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了,查询的性能就可以提高很多了。


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


----------


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









请到「今天看啥」查看全文