写在前面
那天午后,面试官直接壁咚我在会议室门口
拿着我的简历,上来就问我SQL调优
我说,来吧
我已经强大的不要理由
面试官问起Join
心开始颤抖
犹记得,DBA的新人手册开头
《SQL Join要怎么用》
时间很快,会议室的灯开了很久
面试官让我赶紧走,丝毫不对我挽留
还不忘暖心心的安慰我,看看八佾的文章,给自己加加油
正文
就这么说吧,现如今,谁的简历上没有一句精通MySQL原理及调优
,都不要意思递这个简历。今天我们就从Join
这个角度跟面试官来展示一下,我们是如何敢把精通二字写在简历开头的!
Join的流程
让我们先创建两张表t1
和t2
-- 创建表t1,对idx建立普通索引
create table t1
(
id int auto_increment,
idx int null,
constraint t1_pk
primary key (id)
);
create index t1__index_idx
on t1 (idx);
-- 创建表t2,对idx建立普通索引
create table t2
(
id int auto_increment,
idx int null,
constraint t2_pk
primary key (id)
);
create index t2__index_idx
on t2 (idx);
复制代码
现在执行SQL:
select * from t1 straight_join t2 on t1.idx = t2.idx;
复制代码
straight_join
: 是一种以固定方式的连接,强制使用左表作为驱动表。
这个SQL的执行流程是什么样的呢?
- 第一步:从表
t1
读出一行数据ROW - 第二步:从数据行中取出字段
idx
到表t2
中去查找 - 第三步:在
t2
中筛选出满足条件的行,跟t1
读出的数据ROW组装,构成结果集的一行 - 重复步骤一、二、三步,直到
t1
全部查完
这种JOIN的方式,叫做Index Neste-Loop Join
,通过名字我们大概可以知道这种Join的特点:
一是Nested-Loop
嵌套查询,相当于双重for循环。
二是Index 在查询的过程中,我们是可以使用到被驱动表的索引的,被驱动表是树型查找,节约很多的扫描行数。
我们尝试分析一下,Index Neste-Loop Join
的查询流程。
![Index Neste-Loop Join](/Users/huxingbo/Documents/elastic/Index Neste-Loop Join.png)
Join没走索引的场景
刚刚我们嘎嘎聊了,通过索引进行JOIN的流程,那如果被驱动表没有索引呢?直观上来说,根据Index Neste-Loop Join
经验,我们可以仍然采用嵌套循环
。遍历循环t1表的数据,去t2表全表扫描,符合条件的筛选出来,组装成数据集,这种JOIN方式,跟Index Neste-Loop Join
方式很相似,同时,它也有个相似的名字——Simple Nested-Loop Join
但是,我们知道这种效率必然很慢,需要对两张表进行扫描,虽然整体流程没有办法改变,但是能否对其中的一些步骤做优化,是我们想要探索的。
实际上,由于扫描的行数没有改变,也可以时间复杂度上无法再优化,MySQL因此单独开辟了一个空间内存Join Buffer
来把JOIN的操作放到了内存里操作。无索引的Join
流程就变成了这样:
select * from t1 straight_join t2 on t1.idx = t2.idx;
复制代码
第一步:把t1的查询字段,放入内存Join_Buffer
,这个内存区域是线程独享的。
第二步:扫描表t2,把每一行取出来,跟Join_Buffer
里面的数据进行匹配,封装结果集。
细心的你,可能会发现一个问题,虽然Join_Buffer
是内存操作,那么这个内存得多大的,实际上来说是很小的,默认是256K,并且受join_bu!er_size
控制大小。因此,肯定会存在放不下的情况,Mysql把数据拆分成段,分段放,因此这种连接方式被称为Block Nested-Loop Join
。
八股文
通过上面的分析,我们知道了JOIN的执行流程
在这里我想告诉你几个八股文:
- 索引的JOIN可以使用,不走索引的Block,不建议使用。
- 不管是什么JOIN,都建议使用小表作为驱动表
那么在优化中常常提到以小表作为驱动表也是这样的原因。但是我们怎么定义小表呢?
-
严格来说,
我们应该对各个表进行条件筛选,查询的数据字段的总数据量为判断标准
-
Join的优化不应当仅仅局限于索引,小表驱动表,我们还可以通过MRR(Multi-Range Read),5.6的(BKA)Batched Key Access算法优化JOIN
关于MRR和BKA到底是什么呢?我们下次再会?欢迎关注催更