使用join语句,性能比强行拆成多个单表执行SQL语句的性能要好;如果使用join语句的话,需要让小表做驱动表。
  在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与join的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表。
  Index Nested-Loop Join(NLJ)和Block Nested-Loop Join(BNL)算法
  第一个问题:能不能使用join语句?

  1. 如果可以使用Index Nested-Loop Join算法,也就是说可以用上被驱动表上的索引,其实是没问题的;
  2. 如果使用Block Nested-Loop Join算法,扫描行数就会过多。尤其是在大表上的join操作,这样可能要扫描被驱动表很多次,会占用大量的系统资源。所以这种join尽量不要用。

  所以你在判断要不要使用join语句时,就是看explain结果里面,Extra字段里面有没有出现“Block Nested Loop”字样。
  第二个问题是:如果要使用join,应该选择大表做驱动表还是选择小表做驱动表?
4. 如果是Index Nested-Loop Join算法,应该选择小表做驱动表;
5. 如果是Block Nested-Loop Join算法:

  • 在join_buffer_size足够大的时候,是一样的;
  • 在join_buffer_size不够大的时候(这种情况更常见),应该选择小表做驱动表。

  所以,这个问题的结论就是,总是应该使用小表做驱动表。

小结

  通过对Index Nested-Loop Join和Block Nested-Loop Join两个算法执行过程的分析,我们也得到了文章开头两个问题的答案:

  1. 如果可以使用被驱动表的索引,join语句还是有其优势的;
  2. 不能使用被驱动表的索引,只能使用Block Nested-Loop Join算法,这样的语句就尽量不要使用;
  3. 在使用join的时候,应该让小表做驱动表。

  我们在上文说到,使用Block Nested-Loop Join算法,可能会因为join_buffer不够大,需要对被驱动表做多次全表扫描。
  我的问题是,如果被驱动表是一个大表,并且是一个冷数据表,除了查询过程中可能会导致IO压力大以外,你觉得对这个MySQL服务还有什么更严重的影响吗?(这个问题需要结合上一篇文章的知识点)