hash join 的一个疑问

2020-12-31 18:21:32 +08:00
 RudyC

MySQL 在 8.0.18 支持了 hash join,这个版本中只支持 join 的等值条件。此时是以 hash join 是以等值条件做 hash table,再进行匹配( build 和 probe )。

MySQL 8.0.20 后就不再限制等值条件了,那这个版本中是怎么进行 build 和 probe 的呢?

例如官方文档中: ··· mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 JOIN t2 ON t1.c1 < t2.c1\G *************************** 1. row *************************** EXPLAIN: -> Filter: (t1.c1 < t2.c1) (cost=4.70 rows=12) -> Inner hash join (no condition) (cost=4.70 rows=12) -> Table scan on t2 (cost=0.08 rows=6) -> Hash -> Table scan on t1 (cost=0.85 rows=6) ···

https://dev.mysql.com/doc/refman/8.0/en/hash-joins.html
https://mysqlserverteam.com/hash-join-in-mysql-8/

1725 次点击
所在节点    MySQL
2 条回复
lpts007
2020-12-31 20:15:44 +08:00
non-equi-join,哈希函数直接返回原值或前缀就行了。
应该就是把数据从 engine 那里全要过来(区别于 BNJ 的传个 block 进入 engine 进行匹配),server 自己干,配的 buffer 不够就用临时文件。

又想到了 5.6 的索引下推,这不就是一个 bug 修复吗。
RudyC
2021-01-01 17:17:22 +08:00
@lpts007 感谢回复,但还是有几处不明白的地方。


1. 在 non-equi-join 的时,因为没有条件,build 这个阶段是以哪个字段作为 hash table 的 key 呢?
2. 同样在 probe 阶段中,由于没有条件限制,此处是否不需要进行 key exist 而是直接遍历 hash table 的 buffer 以及文件呢?如果需要进行 key exist,那么是选取的哪个字段呢?我测试两份同样的表数据,在 5.7 和 8.0.22 中分别进行 join,5.7 则是以预期的笛卡尔积的结果集( BNL ),8.0.22 中虽然结果集也是一样,不过顺序则是以小表(即用作 hash table 的表)进行倒序排序。

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

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

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

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

© 2021 V2EX