目录
执行步骤
以如下sql为例,一般有两种join算法,先看下NLJ
表中t1和t2的a字段都是索引字段
select * from t1 left join t2 on (t1.a=t2.a);
NLJ(Index Nested-Loop Join)
正常步骤如下:
1.从t1表 取出一行r1
2.查询出t2表中 满足a=r1.a的记录r2,和r1组成一行返回
3.重复1~2步骤 完结
上面如果写程序 就类似嵌套外面两个for循环,在第二个for循环里面 r2记录被是通过驱动表的索引找数据的,这个算法叫 NLJ
驱动表t1是全表扫描,被驱动表t2是扫描的索引树
SNLJ(Simple Nested Loop join)
当join条件中,在被驱动表t2中找数据不是使用的索引树搜索。就是直接使用两个for循环,两个全表扫描 直接笛卡尔集 ,数量大的话这就很牛逼了😂
当然mysql没这么玩,使用了一点优化BNL(Block Nested-Loop Join),具体步骤如下
1.把t1中所有行读到join buffer中
2.循环t2表,把记录一条一条和join buffer中的t1对比,满足条件的作为结果集的一部分返回
优化点就是对比的时候直接和内存中数据对比 会稍微快点
如果执行计划里面出现了Block Nested Loop就最好不要用join了
小结
1.如果要使用JOIN,需要用小表作为驱动表
2.被驱动表要走索引查询