MySQL之in与exists

mysql优化器对in语句的优化是“LAZY”的,对于in,如果不是显示的列表定义,如in('a','b','c'),那么in语句都会被转换为exists相关子查询。如下面独立子查询:

select ...from t1 where t1.a in (selelct b from t2);

优化器会将语句重写为如下相关子查询:

select ...from t1 where exists (select 1 from t2 where t2.b = t1.a)

如果t1,t2分别返回m、n行,那么该查询扫描为o(n+mn)次,首先,exists需要扫描n次,然后相关查询是mn次维度的。
所以,我们不要花费精力去想到底是用in还是exists,因为mysql优化器会自动转换,我们应该花时间来降低表的逻辑IO
怎样降低扫描次数?在不能改变t1的返回结果时,只能考虑优化子查询了了。
譬如1:子查询中如果有group by操作,那么每一次关联外部查询,都会进行一次group by,共进行n次group by操作,
所以可以考虑在相关子查询外面再嵌套一层子查询,做成静态的,这样就不用每次关联查询都去group by了。
2,对子查询建立索引,也能减少逻辑IO
3,可以使用派生表(临时表)重写子查询,进行表连接,以避免子查询与外部查询进行多次比较。

你可能感兴趣的:(MySQL之in与exists)