join算法原理和优化

数据准备

t1 100行
	id 主键
	a 
t2 1000行
	id 主键
	a 索引
	b

Index Nested-Loop Join

sql

select * from t1 straight_join t2 on (t1.a=t2.a);
t1为驱动表,t2为被驱动表

执行流程

1.从表 t1 中读入一行数据 R;
2.从数据行 R 中,取出 a 字段到表 t2 里去查找;
3.取出表 t2 中满足条件的行,跟 R 组成一行,作为结果集的一部分;
4.重复执行步骤 1 到 3,直到表 t1 的末尾循环结束

img

执行效率

由于t2的a有索引,所以大约扫描了200行

Block Nested-Loop Join

sql

select * from t1 straight_join t2 on (t1.a=t2.b);
t1为驱动表,t2为被驱动表

执行流程

1.把表 t1 的数据读入线程内存 join_buffer 中,由于我们这个语句中写的是 select *,因此是把整个表 t1 放入了内存;
2.扫描表 t2,把表 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回。

执行效率

由于t2的b没有有索引,没查t1一条数据,t2差不多都是一次全表查询,扫描最多为100X1000=100000

如果表t1过大

因为join_buffer大小有限,所以出现了下面的执行流程

执行流程2

1.扫描表 t1,顺序读取数据行放入 join_buffer 中,放完第 88 行 join_buffer 满了,继续第 2 步;
2.扫描表 t2,把 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回;
3.清空 join_buffer;
4.继续扫描表 t1,顺序读取最后的 12 行数据放入 join_buffer 中,继续执行第 2 步

执行效率

由于涉及join_buffer,清空和加数据,他的效率更低

优化

小表

综合字段数,记录数小的表作为驱动表

join_buffer设置更大空间

可以减少join_buffer的清空次数

重要:加索引

200和10w,你自己选,如果是10w和10w呢,无法想象
posted @ 2020-01-07 23:37  zx125  阅读(436)  评论(0编辑  收藏  举报