实习期间,看到公司项目的sql代码,一个sql几千行,一度怀疑是自己太菜写不了这么复杂的sql,同时我也在想这个sql这样写到底行不行,下面是我收集的相关资料在此做一个记录:
结论:不建议在sql中使用多表join
主要原因是join的效率比较低
当然几万,几十万得数据量就不需要考虑了
MYSQL是使用了嵌套循环(Neted-Loop Join)的方式来实现关联查询的,就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。
大量使用join的一些问题:
1.性能问题:多表JOIN会增加查询的复杂性,可能导致性能下降,特别是在数据量大时;数据库需要在执行查询时处理更多的行和列,这可能导致更高的I/O操作和内存使用。
2.可读性和维护性:这个就不用多说了一两千行的sql谁看的懂,复杂的Join查询会使得SQL语句变得难以理解,导致维护成本增加。当查询需要频繁修改时,复杂的JOIN会让代码更容易出错。
3.索引利用率:多表JOIN可能会导致数据库无法有效利用索引,影响查询的优化。如果JOIN的字段没有适当的索引,查询性能会显著下降。
4.锁竞争:多表JOIN可能导致更长时间的行锁或表锁,从而增加锁竞争的可能性,影响并发性能。
5.数据完整性:复杂的JOIN查询可能掩盖数据问题或不一致性,使得调试较为困难。难以确保在JOIN查询中返回的数符合业务逻辑和数据完整性要求。
如何优化:
·分解查询:在内存中自己做关联,即先从数据库中把数据查出来之后,再次查询,然后再进行数据封装。
·考虑数据冗余:在某些情况下,可以考虑数据冗余来减少JOIN的需要
·宽表:就是基于一定的join关系,把数据库中多张表的数据打平做一张大宽表,可以同步到Es或者干脆直接在数据库中直接查都可以。
关于分解查询的自己的一点理解:如果数据量少的情况下连两三张表也没什么大的影响,在大数据量的情况下,连接查询会加快性能的消耗,增加数据库的压力,这个时候时牺牲网络IO多次查询来减轻数据库的压力,将原本数据库的压力转移到服务器上。那效果估计就是,减轻数据库压力释放的这点性能可以弥补网络的IO。一方面保护了数据,一方面从另外一个角度提高了性能。