表连接的io cost

变量说明

R表(外部表,驱动表),页数:M,记录行数:n

S表(被驱动表),页数:N,记录行数:n

TS:顺序读

TR:随机读

Nested Loop Join

循环嵌套连接:mysql5.x都只支持NL join,这也是mysql经常被吐槽的点

外部循环中的表称为外部表(驱动表),而内部循环中表称为内部表(被驱动表),通常小表(数据行)驱动大表(数据行),是为了降低连接次数

Simple Nested-Loop Join

执行步骤

1.外部表读取一行记录
2.连接被内部表
3.得到匹配结果
4.执行读外部表下一行记录重复连接匹配,直到表的最后一行循环结束
5.合并结果返回

即:驱动表扫描一次+m次扫描被驱动表

注:mysql并未使用简单嵌套查询

Block Nested-Loop Join

执行步骤

1.外部表读入内存join_buffer
2.内部表读取一行与外部表连接
3.得到匹配结果
4.读取外部表下一批记录读入join_buffer,直到所有行都读入内存循环结束
5.合并结果并返回



即 外部表扫描一次,内部表扫描1~多次

注:内部表扫描次数取决于join_buffer大小,如果join_buffer足够大则能一次把外部表读入join_buffer,如果join_buffer不够大则需要多次读入内存即分成多批blocks.

join_buffer_size mysql各版本默认该设置为128 或 256 或512k。以join_buffer_size 2M计算,通常一条记录4004096字节之间,可用读入5125120条记录,这里也可以引出小表的定义:大概1万行内或小于4M大小.

单独客户端查询(手动查询)也可以调整session的join_buffer_size 值

set session join_buffer_size =536870912 --设置512M