0

0

mysql中JOIN优化与执行流程中的减少扫描策略

P粉602998670

P粉602998670

发布时间:2026-02-26 02:07:17

|

692人浏览过

|

来源于php中文网

原创

mysql join扫描行数超预期是因为驱动表逐行访问被驱动表,若后者未走索引则全表扫描;关键看explain的type字段是否为all/index,需确保on条件列有匹配索引、无函数操作、字符集一致。

mysql中join优化与执行流程中的减少扫描策略

JOIN 执行时为什么扫描行数远超预期

MySQL 的 JOIN 不是先算完左表再匹配右表,而是按驱动表(通常是 EXPLAINid 最小且没依赖其他表的那张)逐行取值,对每行去被驱动表查匹配项。如果被驱动表没走索引,就会全表扫描——10 万行驱动表 × 50 万行被驱动表 = 500 亿行扫描,不是夸张,是真实发生过的线上事故。

关键判断点:看 EXPLAIN 输出里的 type 字段。如果是 ALLindex,基本等于宣告被驱动表正在全扫描。

  • 确保 ONUSING 条件中的列,在被驱动表上有合适的单列索引或联合索引(注意最左前缀)
  • 避免在 ON 子句里对被驱动表字段做函数操作,比如 ON YEAR(t2.create_time) = YEAR(t1.year) 会让索引失效
  • 检查字符集和排序规则是否一致,t1.nameutf8mb4_0900_as_cst2.nameutf8mb4_general_ci,可能导致隐式转换、索引失效

用 STRAIGHT_JOIN 强制驱动表顺序真的安全吗

默认情况下优化器会选它认为“代价最小”的驱动表,但它的统计信息可能过期,或对复杂条件预估不准。这时手动指定 STRAIGHT_JOIN 可跳过优化器决策,直接按 FROM 后顺序执行。

但它不是银弹:一旦业务数据分布变化(比如某字段高基数变低基数),原来最优的驱动顺序可能变成最差。线上曾有案例,加了 STRAIGHT_JOIN 后 QPS 掉 70%,因为驱动表从 1 万行涨到 80 万行,而被驱动表索引刚好因字段类型不一致没生效。

iSlide PPT
iSlide PPT

DeepSeek AI加持,输入主题生成专业PPT,支持Word/PDF等45种文档导入,职场汇报、教学提案轻松搞定

下载
  • 只在 EXPLAIN 明确显示优化器选错驱动表,且你已验证新顺序在当前数据量下更优时使用
  • 必须配合 ANALYZE TABLE 更新统计信息,并定期复查
  • 禁止在没有 WHERE 过滤的多表 JOIN 中滥用,容易触发笛卡尔积放大

如何让 JOIN 只扫被驱动表的必要索引 B+ 树节点

理想情况是:驱动表每行只触发一次索引查找(refeq_ref),而不是扫描整个索引树。这要求被驱动表的连接字段不仅是索引前缀,还要满足“等值查询 + 无 NULL 值 + 类型严格匹配”。

例如 t2.status 上有索引,但 ON t1.status = t2.status 中,若 t2.status 允许为 NULL,MySQL 在某些版本中可能退化为 range 访问,甚至放弃使用该索引。

  • 连接字段设为 NOT NULL,并确保实际数据无空值
  • 联合索引要覆盖 ON 条件全部列,且顺序与 ON 中出现顺序一致(如 ON t1.a=t2.a AND t1.b=t2.b,则索引应为 (a,b),不是 (b,a)
  • 对大表 JOIN,考虑用 IN (SELECT ...) 替代 JOIN —— 如果子查询结果集小且能走主键,有时比嵌套循环更省 I/O
SELECT /*+ USE_INDEX(t2, idx_status_type) */ t1.id, t2.name
FROM orders t1
JOIN order_items t2 ON t1.id = t2.order_id
WHERE t1.created_at > '2024-01-01'
  AND t2.status = 'shipped';

临时表/派生表 JOIN 时的扫描陷阱

JOIN 中包含子查询(如 (SELECT ... ) AS tmp),MySQL 5.7+ 默认将结果物化为内部临时表,且该表默认无索引。后续若拿这个临时表去 JOIN,很可能触发全表扫描。

解决方法不是加索引(内部临时表不支持),而是改写逻辑:把子查询上拉成 JOIN,或用 CTE(MySQL 8.0+)配合 MATERIALIZED 提示控制物化时机。

  • EXPLAIN FORMAT=TREE 查看是否出现 <materialize></materialize> 节点
  • 对简单聚合子查询,尝试用 LEFT JOIN + GROUP BY 重写,避免物化
  • 确认 MySQL 版本是否支持 /*+ NO_MERGE() */ 提示,防止优化器把子查询合并进外层,反而打乱你的索引计划
索引不是加了就有效,JOIN 不是写了就快;真正起作用的是驱动表的行数 × 被驱动表每次查找的平均磁盘页访问数。这两个数字,必须从 EXPLAINrowskey_len 里抠出来算。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

681

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

412

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

286

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

519

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

264

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

392

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

539

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

639

2023.08.14

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

127

2026.02.25

热门下载

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

精品课程

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

共48课时 | 2.4万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 837人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号