为什么阿里巴巴禁止数据库中做多表join?

数据库 MySQL
MySQL是使用了嵌套循环(Nested-Loop Join)的方式来实现关联查询的,简单点说就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。

​阿里出过一个《Java开发手册》,上面有一条规约是禁止超过三张表的join。

图片

而实际操作过程中,我们平时确实在SQL中写JOIN也比较少,两张表JOIN有的时候也有,多张表的JOIN在离线数据分析的时候很多,但是在线系统确实很少。经常有人问我为什么?

其实最主要的原因就是join的效率比较低。

MySQL是使用了嵌套循环(Nested-Loop Join)的方式来实现关联查询的,简单点说就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。

图片

而具体到算法实现上主要有simple nested loop,block nested loop和index nested loop这三种。

而且这三种的效率都没有特别高。

首先,最差的算法就是simple nested loop,他的做法简单粗暴,就是全量扫描连接两张表进行数据的两两对比,所以他的复杂度可以认为是O(n^2)

好一点的算法是index nested loop,当Inner Loop的表用到字段有索引的话,可以用到索引进行查询数据,因为索引是B+树的,复杂度可以近似认为是O(nlogn)

那block nested loop这种算法,其实是引入了一个Buffer,会提前把外循环的一部分结果提前放到多个JOIN BUFFER中,然后内循环的每一行都和多个buffer中的所有数据作比较,从而减少内循环的次数。他的复杂度是O(M*N),这里的M是buffer的个数。

所以,虽然MySQL已经尽可能的在优化了,但是这几种算法复杂度都还是挺高的,这也是为什么不建议在数据库中多表JOIN的原因。随着表越多,表中的数据量越多,JOIN的效率会呈指数级下降。

如果不能通过数据库做关联查询,那么需要查询多表的数据的时候要怎么做呢?

主要有两种做法:

1、在内存中自己做关联,即先从数据库中把数据查出来之后,我们在代码中再进行二次查询,然后再进行关联。 

2、数据冗余,那就是把一些重要的数据在表中做冗余,这样就可以避免关联查询了。

其实数据冗余是互联网业务中比较常见的做法,其实本质上是软件开发中一个比较典型的方案,那就是"用空间换时间",通过做一些数据冗余,来提升查询速度。

在互联网业务中,比较典型的就是数据量大,并发高,并且通常查询的频率要远高于写入的频率,所以适当的做一些反范式,通过做一些字段的冗余,可以提升查询性能,降低响应时长,从而提升并发度。​

责任编辑:武晓燕 来源: Hollis
相关推荐

2020-09-22 11:40:53

BigDecimalequalsJava

2020-09-08 16:25:18

Apache BeancopyJava

2020-07-30 12:16:33

阿里巴巴Apache对象

2018-10-16 15:34:17

阿里巴巴Apache Flin大数据

2013-08-22 09:26:38

去IOE王坚

2023-04-03 07:03:51

阿里巴巴List元素

2019-01-29 15:25:11

阿里巴巴数据库分库分表

2021-03-02 08:01:15

MySQL数据库数据库加密

2016-09-21 20:28:55

阿里巴巴IOE

2020-09-14 09:47:56

Java开发类型

2019-03-04 09:22:52

阿里巴巴foreach Java

2021-09-17 06:28:20

JOIN阿里Java

2019-06-26 07:54:53

ArrayListsubList源码

2021-08-04 17:20:30

阿里巴巴AsyncJava

2022-03-14 09:41:10

POJO类型系统

2022-08-30 16:38:30

阿里巴巴JavaLog4j

2017-12-07 15:07:28

阿里巴巴数据库技术架构演进

2018-12-04 15:54:42

阿里巴巴日志系统

2019-09-04 11:02:54

继承层次组合

2021-10-11 09:32:40

包装类型属性
点赞
收藏

51CTO技术栈公众号