讲师中心 微信公众号
AI工具推荐 视频效率加速

MySQL Hash Join为何没有被优化器采用

阿磊小哥_4397

阿磊小哥_4397

发布时间:2026-08-27 11:26:27

|

492人浏览过

|

来源于php中文网

原创

MySQL未显示“Using join buffer (hash join)”是因为优化器仅在被驱动表无可用索引、满足等值条件、hash_join=on且内存充足时才选用Hash Join;有索引(尤其类型一致、可命中)则优先Index Nested-Loop Join。

mysql hash join为何没有被优化器采用

为什么 EXPLAIN 里看不到 Using join buffer (hash join)

MySQL 优化器是否启用 Hash Join,不是看版本有没有、开关开没开,而是看被驱动表在关联字段上有没有可用索引。有索引 → 默认走 Index Nested-Loop Join(NLJ);没索引 → 才可能选 Hash Join。

常见误判点:

  • ON t1.a = t2.b 中 t2.b 有索引,但类型和 t1.a 不一致(比如 INT vs VARCHAR)→ 触发隐式转换 → 索引失效 → 本该走 NLJ 却走不了,但优化器仍可能因“误判有索引”而拒绝 Hash Join
  • t2.b 上的索引存在,但被 WHERE 条件过滤后选择性极差(比如重复值占 95%),优化器估算 NLJ 成本仍低于 Hash Join → 继续用 NLJ,哪怕实际更慢
  • 复合索引顺序不匹配:索引是 (c1, c2),但 JOIN 条件只用 c2 → 索引无法用于等值查找 → NLJ 失效,但优化器未必立刻切到 Hash Join,尤其当 optimizer_search_depth 较浅时

验证方式很简单:EXPLAIN FORMAT=TRADITIONAL 看 Extra 字段。没出现 Using join buffer (hash join),就说明没走。

被驱动表明明没索引,为什么还是没用 Hash Join

Hash Join 的启用还依赖几个运行时条件,缺一不可:

  • optimizer_switch 中 hash_join=on(默认开启,但可能被配置覆盖)
  • 驱动表不能太大:若驱动表行数 × 每行大小 > join_buffer_size,会退化为分批构建哈希表,开销陡增 → 优化器可能主动弃用
  • 关联字段必须是等值条件(=),且不能带函数或表达式,例如 ON t1.id = UPPER(t2.id) 或 ON t1.ts = DATE(t2.ts) → 直接排除 Hash Join 路径
  • 查询含 RIGHT JOIN 或 FULL OUTER JOIN → Hash Join 不支持,只能回退到 NLJ 或 BNL(8.0.20+ 已移除 BNL,此时可能报错或强制改写)

典型陷阱:join_buffer_size 默认仅 256KB,一张中等宽度的驱动表几千行就溢出。这时即使被驱动表完全无索引,优化器也可能因“预估 Hash Join 内存压力过大”而跳过它。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载

如何强制让优化器考虑 Hash Join

MySQL 没有 USE_HASH 这类 hint(8.0.18 短暂支持后已废弃),但可通过间接手段“引导”:

  • 用 IGNORE INDEX 或 NO_INDEX 提示禁用被驱动表上的关联索引,例如:SELECT /<em>+ NO_INDEX(t2 idx_on_b) </em>/ * FROM t1 JOIN t2 ON t1.a = t2.b
  • 删除或临时禁用被驱动表上“看似可用但实际低效”的索引(比如高重复率的普通索引),让优化器无索引可选
  • 调大 join_buffer_size(需会话级 SET,且注意全局内存压力),降低 Hash Join 的“内存风险评分”
  • 对小表显式指定为驱动表:STRAIGHT_JOIN + 把小表放前面,配合无索引的大表作为被驱动表,提高 Hash Join 入选概率

注意:STRAIGHT_JOIN 只控制连接顺序,不保证算法;最终是否 Hash Join,仍由优化器基于成本模型决定。

LEFT JOIN 场景下 Hash Join 的隐藏风险

MySQL 8.0.18–8.0.20260430 版本中,Hash Join 在多表 LEFT JOIN 中存在已知缺陷:当 join_buffer_size 不足导致哈希表溢出(spill to disk)时,NULL 行可能丢失,结果集行数错误。

触发链路:

  • 多表 LEFT JOIN → 优化器选 Hash Join 作为某一步连接方式
  • 驱动表数据量超 join_buffer_size → 哈希表分批构建并落盘
  • 后续 probe 阶段反复加载/存储中间 record → EQRefIterator 缓存被破坏 → 左表本应补 NULL 的行消失

这不是性能问题,是正确性问题。如果你的业务依赖 LEFT JOIN 的语义完整性(比如报表、ETL),且 MySQL 版本在 20260430 之前,务必检查 EXPLAIN 输出是否含 Using join buffer (hash join) —— 出现即需警惕,建议用 SET optimizer_switch='hash_join=off' 临时规避。

热门AI工具

更多
切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

3803

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

811

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

989

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5621

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2583

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5600

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7361

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1010

2024.04.29

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 176人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 279人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn