MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。
例: user表10000条数据,class表20条数据
select * from user u left join class c u.userid=c.userid
这样则需要用user表循环10000次才能查询出来,而如果用class表驱动user表则只需要循环20次就能查询出来。
由于MySQL使用BTREE结构,内部查询成本(3层查找or4层查找)和外部循环成本不成比例。
因此建议内表走索引,也叫INLJ,但是如果内表是二级索引,效率也低,因为要回表查主键。
如果都是全表扫描(NJL),则相差不多,成本也很高,笛卡尔积。
在有索引的情况下,MySQL会尝试去使用Index Nested-Loop Join算法,在有些情况下,可能Join的列就是没有索引,那么这时MySQL的选择Block Nested-LoopJoin。
Block Nested-Loop Join算法较Simple Nested-Loop Join的改进就在于可以减少内表的扫描次数,甚至可以和Hash Join算法一样,仅需扫描内表一次。