一、概念
MySQL从4.1版本开始支持
子查询
,使用子查询
可以进行SELECT语句的嵌套查询,即一个SELECT查询的结
果作为另一个SELECT语句的条件。子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作
。
1.1、子查询
子查询是 MySQL 的一项重要的功能,可以帮助我们通过一个 SQL 语句实现比较复杂的查询。但是,子查询的执行效率不高
1.2、子查询效率不高
-
1、执行子查询时,MySQL需要为
内层查询语句
的查询结果建立一个临时表
,然后外层查询语句
从临时表 中
查询记录。查询完毕后,再撤销这些临时表
。这样会消耗过多的CPU和IO资源,产生大量的慢查询 -
2、子查询的结果集存储的
临时表
,不论是内存临时表还是磁盘临时表都不会存在索引
,所以查询性能会受到一定的影响 -
3、对于返回结果集比较大的子查询,其对查询性能的影响也就越大
1.3、解决子查询
在MySQL中,可以使用连接(JOIN)查询来替代子查询
。连接查询不需要建立临时表
,其速度比子查询
要快 ,如果查询中使用索引的话,性能就会更好
二、实战
2.1、创建班级表中班长的索引
CREATE INDEX idx_monitor ON class (monitor);
2.2、查询班长的信息
- SQL
EXPLAIN
SELECT *
FROM student stu1
WHERE stu1.`stuno` IN (SELECT monitor
FROM class c
WHERE monitor IS NOT NULL);
-
EXPLAIN
image.png
-
使用
JOIN
替换子查询
DESC
SELECT *
FROM student stu
JOIN class cls ON stu.stuno = cls.monitor
WHERE cls.monitor IS NOT NULL ;
-
EXPLAIN
没有MATERIALIZED .png
2.3、查询不为班长的同学
- SQL
EXPLAIN
SELECT SQL_NO_CACHE a.*
FROM student a
WHERE a.stuno NOT IN (SELECT monitor
FROM class b
WHERE monitor IS NOT NULL);
-
EXPLAIN
image.png
-
使用
JOIN
替换子查询
DESC
SELECT SQL_NO_CACHE *
FROM student stu
LEFT JOIN class cls
ON stu.stuno = cls.monitor
WHERE cls.monitor IS NULL;
-
EXPLAIN
image.png
2.4、小结
尽量不要使用
NOT IN
或者NOT EXISTS
,用LEFT JOIN xxx ON xx WHERE xx IS NULL
替代
网友评论