MySQL多表联查底层执行原理

本文深入探讨了数据库查询中的驱动表概念,解释了在左连接和内连接中如何选择驱动表,以及Mysql如何自动优化选择基表。强调了索引在提高查询性能中的关键作用,并警示了不当使用join查询可能导致的性能问题,特别是对BufferPool的影响。建议在大表关联查询中,如果没有使用索引,应避免使用join。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

驱动表:
基表,就是Mysql先加载到内存中的那张表的数据,然后拿着这条数据去和其他表数据逐个比对。
被驱动表:
多表查询中除了基表,其他表都叫被驱动表。

驱动表的选择
在左(右)连接中,驱动表是由我们自己选择的,选择驱动表后,看where字句有没有驱动表的查询条件,有查询条件,则根据查询条件选出第一条符合条件的数据,然后拿这个数据,跟第一个被驱动表做关联查询,查询出来后,再看where字句有没有第一个被驱动表的查询条件,符合条件的留下,然后拿这条数据去查询第二个被驱动表,查询出来on的数据后,再看where 条件,以此类推。中间有一个不满足where条件的,就扔掉,查询下一条数据。这种方式叫做嵌套循环连接。即基表的每条数据,会跟每个被驱动表比对完后,再进行下一条数据的比对,而不是先是两表所有的数据查询完后,再和第三张表比对。
基表根据on条件查询被驱动表时,on条件有索引肯定查询被驱动表的数据效率就快,这就是为何提倡关联字段都加索引的原因。通过on条件查询出数据后,再根据where条件和select需要的字段,判断是否需要进行回表,还是通过索引就能满足条件,这就和单表查询是一样的了。

内连接查询
内连接查询的过程和上面叙述的过程是一样的,唯一不同的是,内连接查询,是由Mysql自己来决定用谁做基表的。Mysql中有很多算法,来根据不同的情况,选择不同的表作为基表。原则是把结果集最小的那张表,作为基表,来查询其他表。但是也会考虑其他表的索引情况,回表情况等综合因素,最终确定谁是基表,谁是被驱动表查询性能最高。具体的算法介绍可参考Mysql多表连接查询的执行细节

下面摘抄一段关于内连接的知识:

是否应该使用join连接查询?

对于多表间查询,可以使用join关联,也可以拆成多张表的单独查询。对于join关联查询,如果使用不当,很容易造成对被驱动表的多次扫描(Block Nested-Loop join),进而导致IO压力增大,同时多次的扫面被驱动表,会导致被驱动表的数据页被置入mysql buffer-pool的young区域,一次join就替换掉之前真正的热点数据页。

正常一次查询仅全表扫描一次数据的话,数据页会被放入buffer pool的old区域的前端,但是如果一个数据页在第一次使用时,如果不在buffer pool,那么会加载仅buffer pool,放在old区域的前端,但是如果这个数据页在buffer pool,且距离上次使用时间超过1S,也就是join查询时间拆过1S,那么就会把数据页放到buffer pool的young区域,也就是热点区域,这样会导致原先真正的热点数据被替换。这样即使join查询结束了,对mysql的性能有很直接的负面影响,也就是buffer pool内存命中率突然暴跌,查询时间突然变长,很多都需要读取磁盘,需要很长时间才能恢复。

所以,对于大表的关联查询,如果没有使用上索引,也就是on的字段没有索引,通过explain能看到Extra里有Using join buffer(Block Nested Loop),那么就不要使用join了。当然能使用上使用的join查询还是比单表查询来的快的,同时还能很方便的做结果筛选。

关于Buffer Pool的Young区和Old区,以及其LRU算法机制,以后单独进行研究

更正:
sql语句中的左(右)连接中,左(右)表也不一定是基表,mysql的sql优化器会进行分析,也会和内连接的那些算法一样,可能把左(右)连接转化成内连接来执行,只不过返回结果,是以左(右)连接的形式返回回去。
所以,左连接中,左表不一定是基表。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的小小酥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值