一个嵌套子查询的sql优化

Updated on with 0 views and 0 comments

环境

使用阿里云DMS的数据库实验室

创建需要的表

课程表

CREATE TABLE `courses` (
  `cid` int(20) NOT NULL COMMENT '课程ID',
  `name` varchar(32) NOT NULL COMMENT '课程名',
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

随机生成20条数据

学生表

CREATE TABLE `students` (
  `sid` int(11) NOT NULL,
  `name` varchar(32) NOT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

随机生成5W条数据

学生成绩表

CREATE TABLE `sc` (
  `sc_id` int(11) NOT NULL,
  `sid` int(11) NOT NULL,
  `cid` int(11) NOT NULL,
  `score` int(11) NOT NULL,
  PRIMARY KEY (`sc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

生成数据100w条

查询

查询目的

1号课程考100分的学生

查询语句

SELECT s.* FROM `students` s WHERE s.`sid`  IN 
(SELECT `sid`  from `sc` sc WHERE  sc.`cid` = 1 and sc.`score` = 100);

查询时间

220ms

优化

添加cid和score的索引

查询时间

19ms

使用连接查询,先暂时删除索引

查询语句

SELECT s.*
  FROM `students` s
  INNER JOIN `sc` sc on sc.`sid`= s.`sid`
 where sc.`cid`= 1
   and sc.`score`= 100;

查询时间

52ms

给sc表的cid,score添加索引后查询时间

6ms

添加联合索引

ALTER TABLE `yfytest`.`sc` ADD INDEX `idx_score_cid_sid` (`score`, `cid`, `sid`)

查询时间

2ms

总结

  • mysql嵌套子查询效率确实比较低,可以优化成连接查询
  • 建立合适的索引,必要时建立多列联合索引