create table t1 like t2;
JOIN 类型
在 MySQL 中有如下几种常见的 JOIN 类型:
INNER JOIN:内连接,INNER 可以省略 ,返回两个表中字段匹配关系的记录;
LEFT JOIN:左连接,返回左表中的所有记录,即使在右表没有对应匹配的记录;
RIGHT JOIN:右连接,返回右表中的所有记录,即使左表没有对应匹配的记录。
驱动表和被驱动表
MySQL 表使用的关联算法是 Nest Loop Join,它通过将驱动表的结果集作为循环基础数据,
然后从结果集中取出数据到被驱动表中继续查询,最后合并到最终的结果集中。
对应不同的 join 类型,驱动表的选择如下:
1、在左连接中,一般情况下,左表是驱动表,右表是被驱动表;
2、在右连接中,一般情况下,右表是驱动表,左表是被驱动表;
3、内连接比较特殊,优化器会自己选择 数据量较小的表 作为驱动表,而将数据量较大的
表作为被驱动表,即 小表驱动大表。如果我们要指定驱动表,需要使用关键字 straight_join 。
在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算要
放入 join_buffer 的各个字段的总数据量,数据量小的那个表,就是 “小表”,应该作为驱动
表。
如果我们没有指定驱动表,怎么判别优化器选择的驱动表呢?
我们可以通过查看执行计划来判别,在输出的执行计划中,排在第一行的表是驱动表,排在
第二行的表是被驱动表。
比如我们执行 explain select * from t1 join t2 on (t1.a = t2.a) ;
可以看到,优化器选择了 t1 作为驱动表, t2 作为被驱动表。
为了验证内连接是由优化器自己选择驱动表的效果,我们再执行 explain select * from t2 join
t1 on (t1.a = t2.a) ; 看下:
可以看到,结果是一样的,优化器还是选择了 t1 作为驱动表, t2 作为被驱动表。
那为什么优化器会选择让小表驱动大表呢?这就必须聊聊 Nest Loop Join 的算法实现了。
评论