云数据库 MySQL 使用 Hash Join 执行 LEFT JOIN 查询时结果错误

云数据库 MySQL 在使用 Hash Join 执行涉及多表的 LEFT JOIN 查询时,可能出现结果错误的问题。该问题源于 MySQL 8.0.18 引入的 Hash Join 优化器特性,在特定条件下会破坏查询结果集的正确性。

相关产品
云数据库 MySQL 产品页,含版本规格、价格与购买入口。

一、问题描述

当执行满足以下条件的查询时,可能返回错误结果:

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或以上版本,操作方法请参考 升级内核小版本。

赞 (0)
上一篇 4天前
下一篇 4天前