对于join系列语句,大部分开发人员都经常用到。但是对于里面的运行原理,我相信很少人真正认识,下面我们从几个方面介绍下。
为了能够覆盖更多的点,这里复制一位大佬的表和图。我们先建两个表和添加一批数据,注意只有a表的f1有索引,a表和B表的数据不完全一致:
结果集区别
上图可以看出,结果集是不一样的,条件写在ON里,数据有6条,比条件放在where里面多出2条。
算法区别
select*fromaleftjoinbon(a.f1=b.f1)and(a.f2=b.f2)语句执行顺序是:1、先扫描a表的数据,放到join_buffer中,join_buffer的数据结构是数组。2、顺序扫描b表,每一条数据跟join_buffer的a的数据进行on条件判断,匹配则放入结果集中。最后a中未匹配的补上null,合并到结果集中返回。
以上这种查找方法就是Mysql的BlockNextedLoopJoin(简称BNL)算法。b表是没有索引情况下,顺序扫描全表根据驱动表joinbuffer匹配,进而计算结果集!
select*fromaleftjoinbon(a.f1=b.f1)where(a.f2=b.f2)语句执行是:因为where条件中b.f2为null值,且mysql优化器会认为这sql具有优化空间。所以就将这个leftjoin的语句优化为join:select*fromaleftjoinbwherea.f1=b.f1anda.f2=b.f2。也就是即使我们用了leftjoin在这里也不能保证执行顺序,因为优化器会进行优化。现在因为a表f1有索引,优化器优化后变成了b表是驱动表,a表是被驱动表,走的是IndexNested-LoopJoin(简称NLJ)算法。
结论
1、如果要结果集包含左表全部数据,则条件写在ON里
2、如果要保证sql性能,可以写在where里面