LEFT JOIN 嵌套子查询时速度慢的问题

tab_student 为 左表,5000 + 数据,存储三个年级的学生基本信息,通过‘入学年份’区分
yk_2020 为 右表,30000 + 数据,存储学生多次考试成绩,根据‘考试编号’区分
现要查询 2020 级学生的某次成绩,

###代码如下:

SELECT st. 学号,st. 姓名,st. 班级,sc. 总分
FROM (SELECT 学号,姓名,班级 FROM tab_student where 入学年份 = 2020) st
left join (select 学号,总分 from yk_2020 where 考试编号 =’2020313’) sc on st. 学号 = sc. 学号

存在问题,查询需要 5 秒左右。
如果使用以下代码,速度0.2秒,但不是想要的结果,因为,有的学生没有考试成绩,就会被过滤掉,不能显示左表数据。
#####

SELECT st.学号,st.姓名,st.班级,sc.总分
FROM tab_student st left join yk_2020 sc on st.学号=sc.学号
where st.入学年份=2020 and sc.考试编号=2020313

有没有办法能优化。特请指点。感激。 可以联系qq:52128402
链接:https://pan.baidu.com/s/1vWPgBppxwQaPVDWgsgD4sw?pwd=6666
提取码:6666
数据文件已传到网盘。

  1. 创建索引
    CREATE INDEX index_tab_student_id ON tab_student (学号,入学年份);
    CREATE INDEX index_yk_2020_id ON yk_2020 (学号,考试编号);
    
  2. 执行查询计划确认你的索引有生效,如果还慢把结果贴出来,多半是你的索引没生效
    explain
    SELECT st.学号,st.姓名,st.班级,sc.总分
    FROM tab_student st
    LEFT JOIN yk_2020 sc ON st.学号 = sc.学号 AND sc.考试编号 = '2019123465'
    WHERE st.入学年份 = '2019'
    
  3. 这个SQL就是你要的结果啦
    SELECT st.学号,st.姓名,st.班级,sc.总分
    FROM tab_student st
    LEFT JOIN yk_2020 sc ON st.学号 = sc.学号 AND sc.考试编号 = '2019123465'
    WHERE st.入学年份 = '2019'
    

在这种情况下,可能有用的索引包括:

1、在 tab_student 表上创建一个按 入学年份 列排序的索引。这将有助于优化查询中的过滤操作。

2、在 yk_2020 表上创建一个按 考试编号 列排序的索引。这将有助于优化查询中的过滤操作。

3、在两个表上分别创建按 学号 列排序的索引。这将有助于优化连接操作。

这些索引可能会帮助查询运行得更快。但是如果想获得更精确的建议,可能需要提供更多信息,例如表结构、数据量和查询执行计划。
望采纳。

望采纳!!点击该回答右侧的“采纳”按钮即可采纳!
可以尝试在 yk_2020 表上建立索引,这样可以加快查询速度。

例如,可以在 yk_2020 表上建立以学号和考试编号为联合索引的索引,这样就可以提高查询速度。

另外,也可以尝试使用EXISTS关键字优化查询,我给你个例子:

SELECT st.学号,st.姓名,st.班级,sc.总分
FROM tab_student st
LEFT JOIN yk_2020 sc ON st.学号 = sc.学号 AND sc.考试编号 = '2020313'
WHERE st.入学年份 = 2020 AND EXISTS (SELECT 1 FROM yk_2020 WHERE 学号 = st.学号 AND 考试编号 = '2020313')

这个要分2步操作:

1、建立索引

ALTER TABLE `yk_2020` ADD INDEX `考试编号` (`考试编号`);
ALTER TABLE `yk_2020` ADD INDEX `学号` (`学号`);

ALTER TABLE `tab_student` ADD INDEX `学号` (`学号`);
ALTER TABLE `tab_student` ADD INDEX `入学年份` (`入学年份`);

2、查询sql


```sql
SELECT a.学号,a.班级,b.总分 
FROM  tab_student  a LEFT JOIN yk_2020  b ON a.`学号`=b.`学号` AND b.`考试编号`='2020313' 
WHERE a.`入学年份`=2020

```

#这样呢?

SELECT st.学号,st.姓名,st.班级,sc.总分
FROM tab_student as st
left join (select 学号,总分 from yk_2020 where 考试编号=’2020313’) as sc 
on st.学号 = sc.学号 where 入学年份 = 2020

曲线救国,使用创建临时表的方法,把右表数据筛选到临时表,然后用临时表与左表连接,虽然多了一道程序,但是速度提升到1秒以内,
如果大家有更好的方法,望不吝赐教,感激不尽。

我平常写sql也都是按照第二种写的,没遇到问题