Shell 高阶开发实战MK
download:链接:pan.baidu.com/s/1mKXE7E4p… 提取码:2z0i --来自百度网盘超级会员V4的分享
在实践开发中,置信大多数人都会用到join停止连表查询,但是有些人发现,用join仿佛效率很低,而且驱动表不同,执行时间也不同。那么join到底是如何执行的呢?
这里有两个表t1,t2
能够看到,驱动表是的type是ALL,所以是全表扫描,被驱动表有a索引,left join的时分,用到了a这个索引,因而这个语句执行流程是:
-
从表t1中读入一行数据
-
从数据行中,取出a字段到表t2里去查找
-
取出表t2中满足条件的行,跟t1的数据组成一行,作为结果集的一局部
-
反复上面操作,直到t1的数据取完为止
经过上面所述,假如我们选择驱动表的话,就要选择小表来做驱动表。否则大表做驱动表是要查询一切的,效率会低很多。当然,前提是"能够运用被驱动表的索引"
这里我们把sql语句改一下:
explain select * from t1 left join t2 on t1.a=t2.b;
复制代码
结果就是两个表都要全表扫描,这里我们看到,Extra显现的是(Using where; Using join buffer (Block Nested Loop))
这个其实是MySQL对join不走索引全表扫描做了一个优化,简称BNL。
BNL流程:
-
把表t1的数据读入线程内存join_buffer中,这里我们是把整个表t1放入内存中。
-
扫描表t2,把表t2中的每一行取出来,跟join_buffer中的数据做比照,满足join条件的,作为结果集的一局部返回。
这里,我们两个表都是做的全表扫描,所以不论是哪个表做驱动表都是执行耗费都是一样的。
假如一个表的数据太大了,基本装不下一切数据的话,就采用分段放。也能够修正join_buffer_size。
针关于有索引的被驱动表,MySQL5.6版本开端增加了Batched Key Access(BKA)的新特性
关于多表join语句,当MySQL运用索引访问第一个join表的时分,运用join_buffer来搜集第一个操作对象生成的相关列的值。BKA构建好key之后,经过MRR接口提交给引擎做查询。