问题概述
云数据库 MySQL 在使用 Hash Join 执行涉及多表的 LEFT JOIN 查询时,可能出现结果错误的问题。该问题源于 MySQL 8.0.18 引入的 Hash Join 优化器特性,在特定条件下会破坏查询结果集的正确性。
问题详情
问题描述
当执行满足以下条件的查询时,可能返回错误结果:
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 算法,虽然可能牺牲部分性能,但可确保结果正确性。