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/
1
lpts007 2020-12-31 20:15:44 +08:00
non-equi-join,哈希函数直接返回原值或前缀就行了。
应该就是把数据从 engine 那里全要过来(区别于 BNJ 的传个 block 进入 engine 进行匹配),server 自己干,配的 buffer 不够就用临时文件。 又想到了 5.6 的索引下推,这不就是一个 bug 修复吗。 |
2
RudyC OP @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 的表)进行倒序排序。 |