当前位置: 首页 > 科技观察

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

时间:2023-03-20 12:31:05 科技观察

阿里出台了《Java开发手册》,里面有个规定,禁止三张以上表的join。在实际操作过程中,我们通常不会在SQL中写JOIN,有时会出现两张表JOIN的情况。离线数据分析的时候多表的JOIN比较多,但是在线系统确实很少。人们经常问我为什么?其实主要原因是join的效率比较低。MySQL使用嵌套循环(Nested-LoopJoin)的方式来实现关联查询。简单来说就是需要经过两层循环,以第一个表为外循环,第二个表为内循环,外循环的每条记录与内循环的记录进行比较,满足条件的输出。在算法实现上,主要有简单嵌套循环、块嵌套循环和索引嵌套循环三种。而且这三者都不是特别有效。首先,最糟糕的算法是简单的嵌套循环。它的方法简单粗暴,就是扫描并连接两个表进行数据的两两比较,所以它的复杂度可以认为是O(n^2)。更好的算法是索引嵌套循环,当InnerLoop表对字段使用索引时,可以使用索引查询数据,因为索引是B+树,复杂度可以近似认为是O(nlogn),blocknestedloop算法,其实是引入了一个Buffer,将外层循环的部分结果预先放入多个JOINBUFFER中,然后将内层循环的每一行与多个buffer中的所有数据进行比较,从而减少内循环的数量。它的复杂度是O(M*N),其中M是缓冲区的数量。因此,虽然MySQL做了尽可能的优化,但是这些算法的复杂度还是相当高的,这也是为什么不建议在数据库中进行多表join的原因。随着表数量的增加,表中数据量的增加,JOIN的效率会呈指数下降。如果不能通过数据库做关联查询,当需要查询多张表的数据时怎么办?主要有两种方法:1、自己在内存中进行关联,即先从数据库中查到数据后,再在代码中进行二次查询,再进行关联。2、数据冗余,即在表中做一些重要的数据冗余,避免关联查询。事实上,数据冗余是互联网业务中比较普遍的做法。其实本质上是软件开发中的一个典型解决方案,即“以空间换时间”,通过做一些数据冗余来提高查询速度。在互联网业务中,典型的数据量大,并发度高,查询频率通常远高于写入频率,所以适当的反范式和一些字段的冗余可以提高查询性能,以减少响应时间,从而提高并发性。