mysql驱动语句 mysql的连接驱动是什么( 二 )


straight_join使用示例
select * from A as a straight_join B as b on a.id = b.id;
上面的SQL语句在执行的过程中,总是会先读取straight_join前面的A表到join_buffer中,然后再去读取B表中的数据,以此去和join buffer中的A表去匹配 。匹配上的则是表示放入最后的结果集中,匹配不上的则丢弃 。
所以在straight_join语句中,左边的表总是驱动表,右边的表总是被驱动表 。从下图可以看做结论:

mysql驱动语句 mysql的连接驱动是什么

文章插图
驱动表和被驱动表
概念解释
什么是驱动表? 什么是被驱动表?
驱动表在SQL语句执行的过程中,总是先读取 。而被驱动表在SQL语句执行的过程中,总是后读取 。
在驱动表数据读取后,放入到join_buffer后,再去读取被驱动表中的数据,来和驱动表中的数据进行匹配 。如果匹配上则作为结果集返回,否则丢弃 。
如何区分驱动表和被驱动表
我们对于一个已有的SQL语句,我们应该怎么判断这个SQL语句中哪个表示驱动表?哪个表示被驱动表呢?
可以使用explain命令一下SQL语句的执行计划 。在输出的执行计划中,排在第一行的表是驱动表,排在第二行的表是被驱动表 。
join中如何写驱动表和被驱动表
了解了驱动表和被驱动表的概念之后,那么我们在平时写SQL语句的时候,该怎么判断我们所写的SQL语句中哪个是驱动表,哪个是被驱动表?
left join
下面的SQL中,A是驱动表,B是被驱动表 。left join的左表示驱动表,右表示被驱动表 。
select * from A as a left join B as b on a.id = b.id;
上述A left join B连接查询的执行计划如下,从中可以看出A是驱动表,B是被驱动表 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
right join
下面的SQL中,A是被驱动表,B是驱动表 。right join的右表示驱动表,左表示被驱动表 。
select * from A as a right join B as b on a.id = b.id;
上述A right join B连接查询的执行计划如下,从中可以看出B是驱动表,A是被驱动表 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
inner join
对于inner join而言,MySQL会选择小表作为驱动表,大表作为被驱动表 。下面我做一些实验来说明这个大表和小表的定义是什么 。
A、B的表结构和数据行数如下,A表中有3行数据,B表中有6行数据 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
mysql驱动语句 mysql的连接驱动是什么

文章插图
select * from A as a inner join B as b on a.id = b.id;
上述A inner jion B连接查询的执行计划如下,可以看出A是驱动表,B是被驱动表,这里mysql认为A是小表,B是大表 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
A、B的表结构和数据行数如下,和前面的例子相比,A表中的数据行数增加到了27行数据,而不是原先的3行记录 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
mysql驱动语句 mysql的连接驱动是什么

文章插图
select * from A as a inner join B as b on a.id=b.id;
上述A inner jion B连接查询的执行计划如下,可以看出B是驱动表,A是被驱动表,这里mysql认为B是小表,A是大表 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
基于上面的例子,我们把我们的SQL语句修改一下,A和B表的数据行数仍然为27和6 。但是我的SQL语句中增加一个where条件,如下所示:select * from A as a inner join B as b on a.code = b.code where a.id <= 10;select * from A as a inner join B as b on a.code = b.code where a.id <= 11;
最后的执行计划如下图所示,从图中可以看出
当where条件是<=10的时候,A表示驱动表,B表示被驱动表 。当where条件是<=11的时候,B表示驱动表,A表示被驱动表 。
mysql驱动语句 mysql的连接驱动是什么

文章插图
为什么会有这个奇怪的现象?
这是因为两个表在进行关联查询的时候,是根据真正参与关联查询的数据行和列所占用的空间大小来确认谁作为驱动表谁作为被驱动表的 。上述的例子中,当a.id<=10的时候,A表参与关联的数据行和列是A中所有的列,然后是10行数据 。这些行和列组成的数据占用的空间大小刚好比B表的所有列加上它的所有行所占用的空间小,所以此时选择A表作为驱动表 。而当a.id<=11的时候,A表参与关联的数据行和列是A中所有的列,然后是11行数据 。这些行和列组成的数据占用的空间大小刚好比B表的所有列加上它的所有行所占用的空间大,所以此时选择B表作为驱动表 。


推荐阅读