ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL多表联查底层执行原理

2022-02-11 10:34:39  阅读:344  来源: 互联网

标签:多表 join 基表 buffer 查询 MySQL 驱动 联查 数据


驱动表:
基表,就是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算法机制,以后单独进行研究

标签:多表,join,基表,buffer,查询,MySQL,驱动,联查,数据
来源: https://blog.csdn.net/qq1309664161/article/details/122873951

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有