mysql底层join算法

发布时间 2024-01-09 10:52:46作者: 霸王龙168

 

暴力 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 算法 循环次数少了百分之九十九,但是效率肯定没高那么多,毕竟是一次匹配多个