暴力 Nested-Loop Join
走索引的 index-Nested-Loop Join
缓冲块的 blocked-Nested-Loop Join
mysql join 底层实现_mysql join实现算法-CSDN博客
走index loop join ,说明如果联表走主键,就算条件不走主键也会转成主键再收索
selet * from t1 left jon t2 on t1.id = t2.t1_id
如果要走索引,需要对t2表的t1_id建立索引
那么联表的时候就会走t2表的t1_id索引,不会多次嵌套循环
感觉如果后面又where条件的话可以先来一次嵌套子查询,过滤一次数据,
例如
语句一 selet * from t1 left jon t2 on t1.id = t2.t1_id where t1.name = 'test' 和
语句二 select * from (select * from t1 where t1.name = 'test') left join t2 on t1.id = t2.t1_id
假设t1.name 和 t2.t1_id 都没有索引,
表t1和t2都是一万条数据
语句一 走blocked loop 进行 一万/256 *一万次 = 390625 次 循环匹配,然后再根据test过滤
t1和t2的数据都是一一对应的,test过滤时再对一万条数据进行全表扫描
语句一执行过程就是 39万次匹配和一次一万条数据的全表扫描
语句二
先对t1进行全表扫描,假设有十个 test(不到256个都是一次blocked loop),就是一万次循环匹配
语句二执行过程就是 一次一万条数据的全表扫描加一万次循环匹配
上面的例子不知道对不对,我猜的
假设t2.t1_id 加了索引 b+树有两层
语句一 也要循环匹配两万次,还要回表查询,还要对联表结果全表扫描
语句二 全表扫描,全表扫描后 t1剩下十条, 联表 再用索引,再回表 ,还是比语句一强
假设上面是对的,在极端情况下 t1.name全部是test 语句一和语句二效率相同
block_nested_loop的默认大小是256KB 假设一条数据1KB, blocked loop匹配次数 比simple loop 算法 循环次数少了百分之九十九,但是效率肯定没高那么多,毕竟是一次匹配多个