一、问题描述
当执行满足以下条件的查询时,可能返回错误结果:
1. 使用 LEFT JOIN 连接多个表。
2. 优化器选择使用 Hash Join 算法。
二、触发条件
MySQL 8.0.18版本引入 Hash Join 作为默认的 Join 算法,替代了原有的 Block Nested Loop(BNL)。问题发生的路径如下:
LEFT JOIN + 多表 ↓优化器选择 Hash Join(MySQL 8.0.18+) ↓join_buffer_size 不足 ↓Hash Join 溢出到磁盘(spill to disk) ↓行数据在 buffer 中被反复 Store/Load ↓EQRefIterator 缓存的 record[0] 被 AggregateIterator 破坏 ↓NULL 行丢失 → 查询结果错误
三、问题表现
·查询返回的行数不正确。
·LEFT JOIN 中应该补充的 NULL 行丢失。
·数据聚合结果异常。
四、涉及问题的内核版本
MySQL 8.0 20260430之前的版本。
五、应急规避方案
如遇此问题,可通过以下方式临时规避:
SET optimizer_switch='block_nested_loop=off';
该设置会禁用 Hash Join,使查询回退到传统的 Nested Loop 算法,虽然可能牺牲部分性能,但可确保结果正确性。
六、长期版本修复(推荐)
将内核版本升级至 MySQL 8.0 20260430或以上版本,操作方法请参考 升级内核小版本。