为何SELECT xxx IN (SELECT xxx)语句的select_type不是SUBQUERY?
两种子查询的执行差异解析
先明确你的测试场景:创建了两张结构一致的自增主键表t1、t2,执行两条看似相似的查询,却得到不同的select_type:
-- 创建表与插入数据 create table t1(id int(10) auto_increment primary key, content varchar(100) null); create table t2(id int(10) auto_increment primary key, content varchar(100) null); insert into t1(content) values(concat('t1_', floor(1+rand()*100))); insert into t2(content) values(concat('t1_', floor(1+rand()*100)));
两条查询的核心差异在于MySQL查询优化器的处理逻辑不同:
1. = 子查询:标量子查询,独立执行
explain select * from t1 where id = (select id from t2); 里的子查询是标量子查询,因为=运算符要求右侧子查询必须返回单个值。
MySQL会把这个子查询当作独立的查询单元先执行,得到结果后再代入主查询匹配t1的id,所以explain里的select_type标记为SUBQUERY。
注意:如果t2表中存在多条数据(比如插入多行),这个查询会直接报错,因为子查询返回了多个值,不符合=的要求。
2. IN 子查询:被优化为JOIN查询,无独立子查询
explain select * from t1 where id in (select id from t2); 中的IN子查询,被MySQL优化器重写为等价的JOIN语句,类似:
select t1.* from t1 inner join t2 on t1.id = t2.id;
重写后,整个查询变成了普通的表连接操作,没有独立的子查询执行步骤,所以explain里的select_type显示为SIMPLE。这种优化可以利用两张表的主键索引(id是主键)高效匹配数据,即使t2有多条数据也能正常执行,通常比独立子查询的效率更高。
内容的提问来源于stack exchange,提问作者hankeyyh
相关产品推荐
相关产品推荐

