生产环境为啥尽量不用join
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产环境为啥尽量不用join相关的知识,希望对你有一定的参考价值。
参考技术A 公司的mysql规范里一定有对join使用的限制,要么是生产环境不能使用联表查询,要么是join不能超过3个表,而且还要经过leader审批后才能使用。今天就分析join语句的性能,以及为什么对join有这么多限制。先建立两张表,test1和test2,向test1中插入1000条数据,test2中插入100条数据。两张表的表结构相同。
一,执行select * from test2 left join test1 on test1.m = test2.m;
第一行语句表示test2表是全表扫描,test1表用到了索引。
这条语句将test2作为驱动表,test1作为被驱动表。遍历test2中表的行,然后到test1中去比对(用到了索引),比对成功的,返回客户端。
二,执行select * from test2 left join test1 on test1.n = test2.n;
由于n字段没有索引,explain显示两张表都需要全表扫描。“Using join buffer”的意思是两张表在对比的时候,将数据取到join buffer中,也就是内存中的一块区域,虽然时间复杂度没变,但在内存中比较可以提高速度。
如果explain中看到了"Using join buffer",就说明需要优化join语句了。
如果不用join语句,由业务自己开发,整体流程是:
● 将test2表的数据全部取出select * from test2;
●循环取出的数据,select * from test1 where m = test1.m;
可以看到,自己开发在时间复杂度上与使用join差别不大,但流程更清晰。
如果你能对join把握的很好,确实可以使用join,但是如果join的表过多,即使分析explain也很麻烦,也不利于后面的开发维护。
使用join还会引发其他的问题吗?
会。假设我们查询的表是一张非常大的表,而且不经常使用,而我们的join语句又写的不好,就需要对表做多次扫描。mysql在扫描到数据之后,会放进内存中,对于长时间不使用的会淘汰(LRU算法),大量的冷表查询,会导致mysql内存命中率降低,从而影响线上的其他业务,这是生产环境限制使用join的重要原因之一。 还有一个原因就是,如果未来要拆库拆表,再处理join语句就会比较麻烦。
以上是关于生产环境为啥尽量不用join的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Google Cloud Messaging 通知不适用于 iPhone 生产环境?
为啥不应该在 Liferay 的生产环境中使用 HSQLDB?
Rails 生产环境中的 config.assets.compile=true,为啥不呢?