0

0

mysql中连接查询中的索引优化技巧

P粉602998670

P粉602998670

发布时间:2026-01-08 00:54:00

|

452人浏览过

|

来源于php中文网

原创

JOIN字段必须加索引,否则被驱动表将全表扫描;索引需建在ON子句列上,注意类型一致、最左前缀及避免函数操作。

mysql中连接查询中的索引优化技巧

JOIN 字段必须加索引,否则直接变全表扫描

MySQL 在执行 INNER JOINLEFT JOIN 等连接操作时,如果 ON 条件中的字段没有索引,优化器大概率放弃使用索引,对被驱动表做全表扫描。哪怕主表只返回 1 行,被驱动表仍可能扫几万行。

常见错误现象:EXPLAIN 结果中 typeALLindexrows 值远超预期,Extra 出现 Using join buffer (Block Nested Loop)

  • 索引必须建在 ON 子句里实际参与比较的列上,不是 SELECT
  • 复合索引要注意最左前缀:若写 ON t1.a = t2.a AND t1.b = t2.b,则 t2(a,b) 有效,t2(b,a) 通常无效
  • 关联字段类型要严格一致:比如 INTBIGINT 隐式转换会导致索引失效;VARCHAR(50)VARCHAR(100) 一般不影响,但字符集或排序规则不同(如 utf8mb4_0900_as_cs vs utf8mb4_general_ci)会拒绝走索引

驱动表选择影响索引是否生效

MySQL 的嵌套循环连接(Nested-Loop Join)中,先查的表叫驱动表,后查的叫被驱动表。优化器通常选小结果集作驱动表,但有时判断失误,导致本该走索引的被驱动表被迫全表扫描。

可强制指定驱动顺序:用 STRAIGHT_JOIN(仅限 INNER JOIN),把预估更小的表放在 FROM 后,大表放 JOIN 后,并确保大表的 ON 字段有索引。

SELECT STRAIGHT_JOIN a.id, b.name 
FROM small_table a 
JOIN big_table b ON a.ref_id = b.id;
  • 检查 EXPLAINtable 列顺序,确认哪张是驱动表
  • rows 值大的那张表,务必确保其 ON 字段有索引
  • 避免在 ON 条件中对字段做函数操作,例如 ON YEAR(t1.create_time) = t2.year 会让 t1.create_time 索引失效

覆盖索引 + JOIN 可避免回表,但需注意字段顺序

当被驱动表的查询字段全部包含在某个索引中(即覆盖索引),MySQL 就不用回主键索引捞数据,能显著减少 I/O。但这要求索引把 ON 字段放在前面,查询字段放后面。

SeoShop
SeoShop

SeoShop网店系统全站纯静态html生成更符合搜索引擎优化,并修改了以前许多js代码,取消了连接地址的js代码更换为纯div+css格式,并且所有文件可自定义url和文件名,自定义内部连接,自定义外部连接,等多个符合SEO搜索引擎优化的设置,让您的网店更容易让搜索引擎收录. 简单易用 极速网店真正做到以人为本、以用户体验为中心,能使您快速搭建网上购物网站。后台管理操作简单,一目了然,没有夹杂多

下载

例如:需要 SELECT b.name, b.status FROM a JOIN b ON a.bid = b.id,则推荐建索引 b(id, name, status),而不是 b(name, status, id) —— 后者无法用于 ON 匹配。

  • 复合索引中,等值条件字段(=)放最左,范围条件(>, BETWEEN)放中间,查询字段放最后
  • 如果 SELECT 中用了 ORDER BY b.name 且想避免 filesort,索引需包含 name 并满足排序需求(如 b(id, name) 可支撑 ORDER BY name,但前提是 id 是等值过滤)
  • WHERE 条件里的单表过滤字段也应纳入索引,例如 WHERE a.type = 1 AND b.status = 'active',则 b(id, status, name) 更优

多表 JOIN 时,中间表索引容易被忽略

三张及以上表连接时,MySQL 会按一定顺序执行两两 JOIN。第二步 JOIN 的“被驱动表”可能是第一步的结果集(临时表),但更多时候仍是原始物理表。很多人只给首尾两张表建索引,漏掉中间表的 ON 字段索引。

典型场景:orders JOIN order_items ON orders.id = order_items.order_id JOIN products ON order_items.product_id = products.id。这里 order_items 是中间表,它既被 orders 驱动(需 order_id 索引),又被 products 驱动(需 product_id 索引)——两个字段都得单独或联合建索引。

  • EXPLAIN FORMAT=TREE(MySQL 8.0+)看真实执行计划,确认每一步的驱动/被驱动关系
  • 中间表上建议建联合索引,如 order_items(order_id, product_id),兼顾两个方向的 JOIN
  • 避免 SELECT *,尤其在多表 JOIN 中,它会放大回表和临时表开销,让索引收益打折
索引不是建了就万事大吉,关键得出现在执行计划里真正被用上的位置——而那个位置,往往藏在驱动顺序、字段类型、索引结构的细节里。

相关专题

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

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

657

2023.06.20

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

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

244

2023.06.21

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

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

280

2023.07.18

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

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

514

2023.07.19

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

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

252

2023.07.25

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

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

386

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

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

527

2023.08.11

mysql忘记密码
mysql忘记密码

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

596

2023.08.14

java学习网站推荐汇总
java学习网站推荐汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

6

2026.01.08

热门下载

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

精品课程

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

共48课时 | 1.7万人学习

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

共3课时 | 0.3万人学习

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

共1课时 | 785人学习

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

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