前提是join的列有索引,第一个表扫描部分行后存放在join_buffer中,然后被join的表和存放在join_buffer的记录匹配,减少调用存储引擎的次数。
explain format=tree select * from departments inner join dept_manager using(dept_no);
1 2 3 4 |
-> Batched key access inner join -> Batch input rows -> Index scan on departments using dept_name (cost=1.90 rows=9) -> Multi-range index lookup on dept_manager using dept_no (dept_no=departments.dept_no) |
join列无索引且是相等join, 对一个表创建临时的hash表,然后扫描第二个表的时候使用hash和第一个表匹配
explain format=tree select * from employees e1 inner join employees e2 using (first_name) where e2.last_name like 'Bit%';
1 2 3 4 5 6 |
| -> Inner hash join (e1.first_name = e2.first_name) (cost=996684002.49 rows=996649681) -> Table scan on e1 (cost=0.21 rows=299512) -> Hash -> Filter: (e2.last_name like 'Bit%') (cost=30183.45 rows=33276) -> Table scan on e2 (cost=30183.45 rows=299512) |
感觉这个输出有点乱,是不是table e2的信息应该在e1的前面更直接?
https://dev.mysql.com/worklog/task/?id=2241
https://www.percona.com/blog/2019/10/30/understanding-hash-joins-in-mysql-8/
https://dev.mysql.com/doc/refman/8.0/en/hash-joins.html
Posted in: IT人生
Comments are closed.