生产环境为啥尽量不用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 生产环境?

vue生产环境图片无法显示200

为啥不应该在 Liferay 的生产环境中使用 HSQLDB?

Rails 生产环境中的 config.assets.compile=true,为啥不呢?

为啥不在 Vue 和 Vue Router 生产环境中渲染我的组件?

部署到生产:为啥 CloudKit 删除订阅类型?