目录
0 引言
针对mysql中连接(join),分组(group by),排序(order by)语句查询过程的一些知识总结,主要学习资源来自极客时间的《mysql实战45讲》与《mysql是怎样运行的》
1 连接语句
CREATE TABLE `t1` (
`id` INT(11) NOT NULL,
`a` INT(11) DEFAULT NULL,
`b` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `a` (`a`)
) ENGINE=INNODB;
创建一个如上的表t1,并插入100条数据,然后创建一个和表t1结构一样的表t2不过插入1000条数据。然后对t1和t2执行表的连接查询,根据查询语句的不同我们MySQL共有两种进行连接查询的算法,分别是NLJ和BNL算法,具体介绍如下
1.1 NLJ算法
当我们被驱动表上有索引可以使用的时候采用的就是NLJ算法,比如执行以下语句:
select * from t1, t2 where t1.a = t2.b;
该语句explain的结果如下:
可以看到t1是驱动表,t2是被驱动表,其中t1走的是全表扫描,t2走的是索引查询,这个语句的执行过程如下:
- 在t1中拿到一条记录R并取出其a值
- 用在t1中拿到的a值在t2的二级索引中找到对应的记录
- 根据前一步找到的记录回表到t2的聚簇索引中找到对应的记录
- 将前一步得到的记录与R合并就得到了最终的记录
- 重复前面四个步骤直到扫描到t1的最后一条记录为止
这就是NLJ算法的执行流程,我们可以看到在t1中100次查询,在t2中也进行了100次查询,最后总共执行了200次的查询过程。
1.2 BNL算法
当我们被驱动表上没有索引可以使用的时候就会用到这个算法,用这个算法的时候会在内存中开辟一块join_buffer使用,比如我们执行下面的语句