You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 5.7 JOIN查询WHERE子句优化疑问:两种查询为何性能一致?

MySQL 5.7关联查询的执行计划优化疑问

场景说明

在MySQL 5.7中有两张表table_a和table_b,各含100000条记录,数据示例如下:

id  name
-----------
1   name_1  
2   name_2  
3   name_3  
4   name_4  
5   name_5
...

表的DDL定义为:

CREATE TABLE `table_a` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `table_b` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

执行的查询语句

原本期望第二条查询性能更优:

第一条查询:

select SQL_NO_CACHE * 
from table_a a inner 
join table_b b on a.name = b.name 
where a.id between 50000 and 50100;

第二条查询:

select SQL_NO_CACHE * 
from (
    select * 
    from table_a 
    where id between 50000 and 50100
) a 
inner join table_b b on a.name = b.name;

预期与实际结果

原以为第一条会先进行100000100000次迭代再过滤结果,后者先过滤table_a得到100条数据再进行100100000次迭代,因此前者性能会远差于后者。但实际两者耗时均为1.5秒,且EXPLAIN结果无实质差异。


解答

MySQL确实对第一条查询做了**谓词下推(Predicate Pushdown)**优化,使其执行逻辑与第二条完全一致。

MySQL的查询优化器会自动调整执行顺序:它不会先做两张表的全表关联,而是优先利用table_a的主键索引快速筛选出id between 50000 and 50100的100条数据,再用这些数据的name字段去关联table_b。这就等价于第二条查询中先通过子查询过滤table_a的逻辑。

另外,由于table_b的name字段没有创建索引,所以关联时需要对table_b做100次全表扫描(对应table_a筛选出的100条数据),这也是两条语句耗时一致的核心原因。


内容的提问来源于stack exchange,提问作者phantomsee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 11:03:15