求助一个关于 mysql join 的问题

28 天前
 a1oyss0925

这几天为了面试在看 mysql 的官方文档,看到关于 Nested-Loop Join 算法的章节。 其中普通的 Nested-Loop Join 倒是好理解,就是类似 for 循环嵌套 for 循环,但是到了第二个 Blocked Nested-Loop Join 我就不太懂了,

A Block Nested-Loop (BNL) join algorithm uses buffering of rows read in outer loops to reduce the number of times that tables in inner loops must be read. For example, if 10 rows are read into a buffer and the buffer is passed to the next inner loop, each row read in the inner loop can be compared against all 10 rows in the buffer. This reduces by an order of magnitude the number of times the inner table must be read.

伪代码:

for each row in t1 matching range {
  for each row in t2 matching reference key {
    store used columns from t1, t2 in join buffer
    if buffer is full {
      for each row in t3 {
        for each t1, t2 combination in join buffer {
          if row satisfies join conditions, send to client
        }
      }
      empty join buffer
    }
  }
}

if buffer is not empty {
  for each row in t3 {
    for each t1, t2 combination in join buffer {
      if row satisfies join conditions, send to client
    }
  }
}

看代码描述就是先从 t1,t2 读取数据,然后存在 buffer 中,最后 t3 再与 buffer 循环判断,感觉好像也没减少数量级啊。 后来去网上查,又得到了不同的解释:一次性缓存多条数据中,并且 t3 是批量判断缓存中的行。其中《 MySQL 实战 45 讲》又提到

从时间复杂度上来说,这两个算法是一样的。但是,Block Nested-Loop Join 算法的这 10 万次判断是内存操作,速度上会快很多,性能也更好。

那就意味着 t1,t2,t3 都是一行一行读取的? 有点懵圈了,求大佬们看看

842 次点击
所在节点    MySQL
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1067259

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX