这时 , 执行流程是这样的
- 从驱动表article中读取数据存放在join_buffer中 , 由于是使用的没有条件的select, 因此会把article全表数据放入内存
- 【算法|为什么不让用join?《死磕MySQL系列 十六》】拿着join_buffer中的数据跟article_comment中的数据进行逐行对比
为了复现
Block Nested Loop
, 咔咔装了三个版本的MySQL , 分别为MySQL8 , MySQL5.5 , MySQL5.7在后两个版本中都使用的是Block Nested Loop
, 但在MySQL8中却发生了变化 。对于hash join 下期会聊到 , 在这个查询过程中 , 对表article、article_comment都做了一次全表扫描 , 因此扫描行数是2000 。
把article中的数据读取到join_buffer中是以无序数组的方式存储的 , 对于article_comment表中的每一行 , 都需要做1000次判断 , 那么就需要判断的次数就是1000*1000=1000万次 。
这时你发现使用分块嵌套循环跟简单嵌套查询扫描行数是一样的 , 但
Block Nested Loop
算法应用了join_buffer的这么一个内存空间 , 因此速度上肯定会比Simple
快很多 。五、总结本期我们用三个问题来总结全文 , 以帮助你更好的理解 。
第一个问题:能不能使用join?
通过三个演示案例 , 现在你应该知道当关联条件的列是被驱动表的索引时 , 是完全没有问题的 , 也就是说当使用索引嵌套查询时 , 是可以使用join的 。
但当使用的是分块嵌套查询 , 这种方式扫描行数为两张表行数的乘 , 扫描行数会非常的大 , 会占用大量的系统资源 , 所以这种算法的join是非常不建议使用的 。
因此当使用join时 , 最大可能的让关联查询的列为被驱动表的索引列 , 若不能达到这个条件则可以考虑表结构设计是否合理
第二个问题:如果使用join , 选择大表还是小表作为驱动表?
好的习惯都是慢慢养成的 , 因此你要记住无论在什么情况下都用小表驱动大表 , 先记住这个结论 。
如果是
Nested-Loop Join
算法 , 应该选择小表作为驱动表 。如果是
Block Nested-Loop Join
, 当join_buffer足够大的时候 , 使用大表还是小表作为驱动表都是一样的 , 但是当join_buffer没有手动设置更大的值时 , 还是应该选择小表作为驱动表 。这里还需要知道一点join_buffer的默认值为在MySQL8.0为256kb 。
第三个问题:什么样的表是小表?
这里的小表不是数据量非常小的表 , 这点一定不能搞错 , 在所有的SQL查询中绝大多数情况是有条件进行筛选的 。
看是否为小表是根据同一条件下两张表那个检索的数据量小 , 那张表就是小表 。
推荐阅读死磕MySQL系列总目录
打开order by的大门 , 一探究竟《死磕MySQL系列 十二》
重重封锁 , 让你一条数据都拿不到《死磕MySQL系列 十三》
闯祸了 , 生成环境执行了DDL操作《死磕MySQL系列 十四》
聊聊MySQL的加锁规则《死磕MySQL系列 十五》
坚持学习、坚持写作、坚持分享是咔咔从业以来所秉持的信念 。 愿文章在偌大的互联网上能给你带来一点帮助 , 我是咔咔 , 下期见 。
- 小米科技|为什么感觉小米12的销量无法超越小米11了?
- 显卡|惠普星13air为什么比14贵?介绍惠普星13air和星14区别哪个好
- 芯片|植物35亿年历史,竟然没进化出一种黑色的花,为什么?
- 红米手机|手机号码,为什么都是11位数?手机号的秘密你知道多少?
- |为什么现在手机都使用玻璃机身?
- 华为p40|为什么华为P40Pro降价了都没人买,而mate40Pro+涨价后却依然抢手
- 哈苏|为什么说有了OPPO Find X5系列就像拥有哈苏?
- 苹果|神回复:为什么美国可以禁止用中国手机?中国不禁止用苹果呢?
- 路由器|家里的WIFI信号时断时续,工作人员真正来检查说“没毛病”,是为什么呢?
- mac|同样顶级的屏幕同样好的扬声器 ,便宜性能还强,为什么不买轻薄本