君哥聊技术

面试官:MySQL 使用多表 JOIN 有哪些危害?

大家好,我是君哥。

多表 JOIN 是好多公司严格禁止的 SQL 写法,那它到底有哪些危害呢?今天来聊一下这个话题。

图片

1.资源压力

多表 JOIN,尤其是 JOIN 涉及的表存在大表的情况下,数据库会承受巨大的计算和内存压力。

在高并发场景下,多表 JOIN 可能占用大量的join buffer,造成内存压力增加,SQL 执行时间增大,进一步造成大量连接不能释放,连接被耗尽。最终结果就是整个数据库实例响应慢,客户端因为获取不到连接而失败。

2.性能风险

JOIN 语句的性能依赖于正确的索引,如果 ON 或 WHERE 子句中的列没有加索引,执行 JOIN 语句需要进行全表扫描。JOIN 的表越多,全表扫描的成本越高,最坏情况下可能达到呈笛卡尔积的数量级。尤其是 JOIN 语句中有大表(比如数据量百万级别)时,一个复杂的多表 JOIN 语句响应时间可能会达到分钟级别,这会造成大量上游系统请求超时,业务不能正常进行。

3.锁等待

InnoDB 默认隔离级别是可重复读,在可重复读隔离级别下,JOIN查询可能会对涉及的行加间隙锁,如果 JOIN 的表比较多,可以会有多张表的多条记录和间隙被锁定,造成其他事务的锁等待,甚至可能造成死锁,这会严重降低系统吞吐量。

4.可维护性差

多表 JOIN 的 SQL 涉及多张表、多个 JOIN 条件,往往 where 子句也会有多个筛选条件,可读性差。而复杂 JOIN 往往包含了复杂业务逻辑,面对需求修改,如果不是 SQL 原作者,很难理解和维护。对测试而言,测试用例也很难覆盖所有场景,导致生成问题。

5.影响分库分表

随着业务量上升,数据量也会变大,单表存储会影响到 SQL 性能,这个时候就需要考虑分库分表。如果一个多张表 JOIN 的 SQL 语句中涉及多张表要分库和分表,那就必须让这些表的同一笔业务数据拆分到同一个数据库节点上,同时 JOIN 的表名也需要修改,这涉及的改造和测试 工作难度非常大。

6.影响信创改造

如果涉及信创改造,多表 JOIN 的 SQL 除了数据迁移外,还需要评估这个 SQL 在新库上的执行效率,给信创改造增加了很多额外的工作。

精品专栏 70 篇,推荐阅读。
又老性能又差,为什么好多公司依然选择 RabbitMQ?

45 个知识点,带你入门消息队列!

引入了 Disruptor 后,系统性能大幅提升!

 从 MySQL 迁移到 GoldenDB,上来就踩了一个坑。

面试官:MySQL BETWEEN AND 语句包括边界吗?

面试官:MySQL Redo Log 和 Binlog 有什么区别?分别用在什么场景?

面试官:使用 MySQL 时你遇到过哪些索引失效的场景

面试官:MySQL表中有2千万条数据,B+树层高是多少?

面试官:MySQL JOIN 表太多,你有哪些优化思路?

感谢阅读,如果对你有帮助,请点赞和在看。欢迎加我微信:zhujinjun86。

号内回复 seata,下载《阿里分布式中间件Seata从入门到精通》

号内回复 beijing,下载我总结的北京上百家知名科技公司

号内回复 aqs,下载《40张图精通Java AQS》