例句:select * from a where id in (select id from b );

对于这条sql语句它的执行计划其实并不是先查询出b表的所有id,然后再与a表的id进行比较。
mysql会把in子查询转换成exists相关子查询,所以它实际等同于这条sql语句:select * from a where exists(select * from b where b.id=a.id );

而exists相关子查询的执行原理是: 循环取出a表的每一条记录与b表进行比较,比较的条件是a.id=b.id . 看a表的每条记录的id是否在b表存在,如果存在就行返回a表的这条记录。

exists查询有什么弊端?
由exists执行原理可知,a表(外表)使用不了索引,必须全表扫描,因为是拿a表的数据到b表查。而且必须得使用a表的数据到b表中查(外表到里表中),顺序是固定死的。

如何优化?
把查询修改成inner join连接查询:select * from a inner join b on a.id=b.id; 


可用EXPLAIN EXTENDED或者DESC来查看SQL执行计划来分析,下面是实际优化SQL,字段和表名做了处理

优化前

SELECT a.good_num, a.cal_date, a.count,a.apply_date, a.name, a.class_num
FROM table1 
where id in (
SELECT max(id) id
FROM table1 
where name = '金属制品有限公司' GROUP BY num
)


优化后
SELECT a.good_num, a.cal_date, a.count,a.apply_date, a.name, a.class_num
FROM table1 a 
inner join 
( SELECT max(id) id
  FROM table1
  where name = '金属制品有限公司' GROUP BY num ) b
on a.id=b.id
where a.count >= 10000


Logo

更多推荐