MySQL学习大纲
我的数据库学习大纲
1、什么是子查询:
- 1.MySQL 从 4.1 版本开始支持子查询,使用子查询可以进行 SELECT 语句的嵌套查询,即一个 SELECT 查询的结果作为另一个 SELECT 语句的条件。
子查询可以一次性完成很多逻辑上需要多个步骤才能完成的 SQL 操作
2、子查询执行效率说明:
- 1.
子查询可以帮助我们通过一个 SQL 语句实现比较复杂的查询。但是子查询的执行效率不高
。其原因在于:- 执行子查询时,MySQL 需要为内层查询语句的查询结果
建立一个临时表
,然后外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表。这样会消耗过多的 CPU 和 I/O 资源,产生大量的慢查询。 - 子查询的结果集存储的临时表,不论是内存临时表还是磁盘临时表
都不会存在索引
,所以查询性能会受到一定的影响。 - 对于返回结果集比较大的子查询,其对查询性能的影响也就越大。
- 执行子查询时,MySQL 需要为内层查询语句的查询结果
在 MySQL 中,可以
使用连接 (JOIN) 查询来替代子查询
。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引的话,性能就会更好
3、举例
3.1.案例1:查询学生表 student 中是班长的学生信息
a.使用子查询
# 创建班级表中班长的索引
CREATE INDEX idx_monitor ON class(monitor);
# 查询班长的信息
EXPLAIN SELECT * FROM student stu1
WHERE stu1.`stuno` IN (
SELECT monitor
FROM class c
WHERE monitor IS NOT NULL
);
b.使用 join
EXPLAIN SELECT stu1.* FROM student stu1 JOIN class c
ON stu1.`stuno` = c.`monitor`
WHERE c.`monitor` IS NOT NULL;
3.2.案例2:查询不为班长的学生信息
a.使用子查询
EXPLAIN SELECT SQL_NO_CACHE a.*
FROM student a
WHERE a.stuno NOT IN (
SELECT monitor FROM class b
WHERE monitor IS NOT NULL)
b.使用 join
EXPLAIN SELECT SQL_NO_CACHE a.*
FROM student a LEFT OUTER JOIN class b
ON a.stuno =b.monitor
WHERE b.monitor IS NULL;
注意:
尽量不要使用 NOT IN 或者 NOT EXISTS,用 LEFT JOIN xxx ON xx WHERE xx IS NULL 替代