没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
44 | 答疑文章(三):说一说这些好问题
2019-02-22 林晓斌
这是我们专栏的最后一篇答疑文章,今天我们来说说一些好问题。
在我看来,能够帮我们扩展一个逻辑的边界的问题,就是好问题。因为通过解决这样的问题,能
够加深我们对这个逻辑的理解,或者帮我们关联到另外一个知识点,进而可以帮助我们建立起自
己的知识网络。
在工作中会问好问题,是一个很重要的能力。
经过这段时间的学习,从评论区的问题我可以感觉出来,紧跟课程学习的同学,对SQL语句执行
性能的感觉越来越好了,提出的问题也越来越细致和精准了。
接下来,我们就一起看看同学们在评论区提到的这些好问题。在和你一起分析这些问题的时候,
我会指出它们具体是在哪篇文章出现的。同时,在回答这些问题的过程中,我会假设你已经掌握
了这篇文章涉及的知识。当然,如果你印象模糊了,也可以跳回文章再复习一次。
joinjoin的写法的写法
在第35篇文章《join语句怎么优化?》中,我在介绍join执行顺序的时候,用的都是
straight_join。@郭健 同学在文后提出了两个问题:
1. 如果用left join的话,左边的表一定是驱动表吗?
2. 如果两个表的join包含多个条件的等值匹配,是都要写到on里面呢,还是只把一个条件写到
on里面,其他条件写到where部分?
为了同时回答这两个问题,我来构造两个表a和b:
表a和b都有两个字段f1和f2,不同的是表a的字段f1上有索引。然后,我往两个表中都插入了6条
记录,其中在表a和b中同时存在的数据有4行。
@郭健 同学提到的第二个问题,其实就是下面这两种写法的区别:
我把这两条语句分别记为Q1和Q2。
首先,需要说明的是,这两个left join语句的语义逻辑并不相同。我们先来看一下它们的执行结
果。
create table a(f1 int, f2 int, index(f1))engine=innodb;
create table b(f1 int, f2 int)engine=innodb;
insert into a values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
insert into b values(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
select * from a left join b on(a.f1=b.f1) and (a.f2=b.f2); /*Q1*/
select * from a left join b on(a.f1=b.f1) where (a.f2=b.f2);/*Q2*/
图1 两个join的查询结果
可以看到:
语句Q1返回的数据集是6行,表a中即使没有满足匹配条件的记录,查询结果中也会返回一
行,并将表b的各个字段值填成NULL。
语句Q2返回的是4行。从逻辑上可以这么理解,最后的两行,由于表b中没有匹配的字段,结
果集里面b.f2的值是空,不满足where 部分的条件判断,因此不能作为结果集的一部分。
接下来,我们看看实际执行这两条语句时,MySQL是怎么做的。
我们先一起看看语句Q1的explain结果:
图2 Q1的explain结果
可以看到,这个结果符合我们的预期:
驱动表是表a,被驱动表是表b;
由于表b的f1字段上没有索引,所以使用的是Block Nexted Loop Join(简称BNL) 算法。
看到BNL算法,你就应该知道这条语句的执行流程其实是这样的:
1. 把表a的内容读入join_buffer 中。因为是select * ,所以字段f1和f2都被放入join_buffer了。
2. 顺序扫描表b,对于每一行数据,判断join条件(也就是a.f1=b.f1 and a.f2=b.f2)是否满足,
满足条件的记录, 作为结果集的一行返回。如果语句中有where子句,需要先判断where部分
满足条件后,再返回。
3. 表b扫描完成后,对于没有被匹配的表a的行(在这个例子中就是(1,1)、(2,2)这两行),把剩
余字段补上NULL,再放入结果集中。
对应的流程图如下:
剩余18页未读,继续阅读
白羊带你成长
- 粉丝: 21
- 资源: 329
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- web期末大作业-HTML+CSS+JS仿王者荣耀官网网站HTML5项目实训源码.zip
- 帕鲁ppt备份只是为了方便
- 3.15 设计vi,产生一个0.0到10.0的随机数,与10.0相乘,然后通过一个字vi将积与100相加后开方
- 3.14 设计vi,比较两个数,如果其中一个数大于另一个数,则点亮LED指示灯
- 08最短路径_Floyd.c
- 02二叉排序树_BinarySortTree.c
- python字符串逆序方法.md
- qt软件开发+代码+注释+自我学习+windows软件开发+图像分割
- python二叉树的遍历.md
- 1cdd0859202f67f8bf6945fd9559ea102d27d11b
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0