暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL tips(十九)——join

爱可可的人生记录仪 2020-02-04
239
使用 join 有什么问题呢,到底能不能用?如果有两个大小不同的表做 join,应该用哪个表做驱动表呢?


Index Nested-Loop Join

在形式上,可以用上被驱动表的索引,称之为“Index Nested-Loop Join”,简称 NLJ。使用 join 语句,性能比强行拆成多个单表执行 SQL 语句的性能要好;如果使用 join 语句的话,需要让小表做驱动表。


Simple Nested-Loop Join

被驱动表没有索引,N*M极其笨重,MySQL不会使用,而是使用下面的算法。


Block Nested-Loop Join

    #STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table. 
    #慎重使用,因为大部分情况下指定的执行顺序并不一定会比优化引擎要靠谱。
    select * from t1 straight_join t2 on (t1.a=t2.b);

    1.把表t1的数据读入线程内存 join_buffer 中,由于这个语句中写的是 select *,因此是把整个表 t1 放入了内存;

    2.扫描表 t2,把表 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回。


    从时间复杂度上来说,与Simple Nested-Loop Join算法是一样的。但是,Block Nested-Loop Join 算法的这 10 万次判断是内存操作,速度上会快很多,性能也更好。join_buffer 的大小是由参数 join_buffer_size 设定的,默认值是 256k。如果放不下表 t1 的所有数据话,策略很简单,就是分段放。如果你的 join 语句很慢,就把 join_buffer_size 改大。


    在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表。


    小结

    如果可以使用被驱动表的索引,join 语句还是有其优势的;

    不能使用被驱动表的索引,只能使用 Block Nested-Loop Join 算法,这样的语句就尽量不要使用;

    在使用 join 的时候,应该让小表做驱动表。


    参考资料:丁奇,MySQL实战45讲



    部分内容来自网络,如有侵权请联系作者删除。


    文章转载自爱可可的人生记录仪,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论