mysql怎么看驱动表 mysql驱动cj

MySQL表连接之驱动表与被驱动表 众所周知, MySQL的驱动表与被驱动表是优化器自动优化选择的结果 (与表连接的前后顺序等无关),我们可以用explain执行计划来知晓:
如上所示,前面一行t1是驱动表 , 后面一行t2是被驱动表 。那么驱动表与被驱动表的选择是否有规律可循呢?下面是百度搜索两个主流的博文对驱动表与被驱动表的阐释:
1. MySQL连接查询驱动表被驱动表以及性能优化 - 阿伟~ - 博客园 博文A 主要结论:
2. mysql驱动表与被驱动表及join优化_java小小小黑的博客-CSDN博客_mysql驱动表和被驱动表博文B 其主要结论:
两个帖子的结论是都差不多,而且还给出了例子来佐证 。那么网上的结论是否权威?是否有普遍性?是否存在缺陷?
让我们来一起打破砂锅问到底 。下面有两张表结构一模一样的表t1,t2:其中t1 100条数据,t2 1000条数据;t1(t2)结构如下:
按照上面博文的结论 , left join左边是t2表 , 应该是驱动表 。我们查看下结果:
与 博文B 中观点1相违背(同理观点2也违背),与实际不符 , 但究竟这是为什么呢?
下面发一张MySQL的执行过程(来源于《MySQL实战45讲》中01讲【一条SQL查询语句是如何执行的】)
so die si ne , 原来sql执行的过程是这样呀 。等等,不对,这跟刚才SQL又有什么关系,上面left join中t2表还是左边的呀 。
我们知道MySQL高版本的性能越来越好,它是不断进行优化迭代的 。远古的mysql版本可能还需要人工把小表放在前面 , 大表放在后面等这些需要人工调优的经验早就已经被解决了 。也就是说我们写的语句,MySQL为了追求更好的效率,它在执行器执行前已经帮我们优化了 。那么实际优化后的sql如何查看呢?用show warning命令:
其中Message就是优化后实际执行的sql语句 , 格式化后如下:
优化后left join左连接变成了内连接(inner) join 。所以用优化后的sql看 , 表t1是小表所以作为驱动表,与实际结果相符 。
left join 竟然优化成了join,太神奇了,但这是为什么呢?原因在于mysql中null与任何值做等值或者不等值比较的时候都是null,即使是select null=null 也是null 。这样where 条件t1.a=t2.a查询条件不会包含t2.a为NULL的行 , 实际效果其实跟join一样,被优化器智能的优化了 。
我们直接看执行计划看实际结果吧:
结果显示t2是驱动表,t1是被驱动表 。t2是1000条数据按理说是大表应该是被驱动表 , 与 博文A ,博文B 的结论又不一致了 。
《MySQL实战45讲》中34讲【到底可不可以使用join】已经讲的很透彻了 , 很深入了,我就不在这里献丑了 。啰嗦几句大概就是驱动表是全表扫描不走索引,所以选被驱动表t1可以走索引 , 不会全表扫描,减少IO次数,性能高 。里面对大表小表的总结 , 简直是精髓,特意在此再次着重强调:
在决定哪个表做驱动表的时候 , 应该是两个表按照各自的条件过滤 , 过滤完成之后,计算参与join的各个字段的总数据量 , 数据量小的那个表,就是“小表”,应该作为驱动表 。
按照上面分析,我们先独立思考下MySQL会选择哪张表作为驱动表呢?
表t1,t2在字段a上都有索引不会全表扫描,其中t1.a=5条件过滤后只有一条,很显然嘛,t1数据量少是小表,肯定是驱动表,错不了,再说了前面的红色粗体已经强调了 , 不会有错的 。
【mysql怎么看驱动表 mysql驱动cj】 有冇搞错?事实又被打脸了 。还记得在开篇我们说过的mysql优化器会对sql语句进行优化的吗?下面我们看下执行计划与优化的sql语句:

推荐阅读