美文网首页MySQL
57-MySQL索引优化与查询优化-子查询

57-MySQL索引优化与查询优化-子查询

作者: 紫荆秋雪_文 | 来源:发表于2022-11-02 18:33 被阅读0次

一、概念

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替代

相关文章

网友评论

    本文标题:57-MySQL索引优化与查询优化-子查询

    本文链接:https://www.haomeiwen.com/subject/wmbjtdtx.html