Join 连表操作

2021-09-14  本文已影响0人  DH大黄

参考文章

https://time.geekbang.org/column/article/79700

https://time.geekbang.org/column/article/80147

NLJ(Index Nested-Loop Join)

对于被驱动表有索引的情况

遍历驱动表,每读出一条驱动表上的数据,都会去被驱动表的索引树上获取满足条件的数据,组成一行作为结果集的一部分。然后重复上述步骤

NLJ优化使用MRR的时候,就会先讲驱动表的数据部分存放到join_buffer中,然后一次性传入一批的关联数据到被驱动表中,加快查询速度

假如驱动表的数据过多,也会有分段放入join_buffer的情况(BKA算法)

BNL(Block Nested-Loop Join)

对于被驱动表没有可用索引的情况

对驱动表做遍历,将数据放入join buffer,然后对第二张表做遍历,在内存中做匹配放入join buffer中

假如驱动表太大,join buffer不够的情况,会分块获取被驱动表的数据,然后逐块去做上述的步骤(被驱动表被扫描的次数增加)

这种情况就不适合使用join去做连表查询了

原因:假设被驱动表也非常大

  1. 被驱动表全表扫描次数增多,io增加

  2. 本身比较的次数也很多

  3. 对buffer pool 影响时间比较久,使业务正常访问的数据页没有机会进入young区

对于BNL的一种优化,mysql 8.0以后的hash join(个人理解:相较于BNL,减少了比较的次数)

http://mysql.taobao.org/monthly/2019/11/02/

使用到BNL的情况(这种情况就需要优化了)

image

常说的小表驱动大表 何谓小表

应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”

上一篇 下一篇

猜你喜欢

热点阅读