请参阅下面的查询
Select count(*) FROM
(Select distinct Student_ID, Name, Student_Age, CourseID from student) a1
JOIN
(Select distinct CourseID, CourseName, TeacherID from courses) a2
ON a1.CourseID=a2.CourseID
JOIN
(Select distinct TeacherID, TeacherName, Teacher_Age from teachers) a3
ON a2.TeacherID=a3.TeacherID
子查询必须用于重复数据删除。
此查询在PostgreSQL中运行正常。但是,如果我在学生表和教师表之间添加条件,根据执行计划,Postgres将错误地嵌套循环加入学生并教授没有直接关系的表。例如:
Select count(*) FROM
(Select distinct Student_ID, Name, Student_Age, CourseID from student) a1
JOIN
(Select distinct CourseID, CourseName, TeacherID from courses) a2
ON a1.CourseID=a2.CourseID
JOIN
(Select distinct TeacherID, TeacherName, Teacher_Age from teachers) a3 ON
a2.TeacherID=a3.TeacherID
WHERE Teacher_Age>=Student_Age
此查询将永远运行。但是,如果我用表替换子查询,它会非常快地运行。如果不使用临时表存储重复数据删除结果,有没有办法在这种情况下避免嵌套循环?
感谢您的帮助。
答案 0 :(得分:1)
您正在使数据库执行大量不必要的工作以实现您的目标。不是将3个不同的SELECT DISTINCT子查询全部连接在一起,而是尝试将基表直接相互连接,并让它只处理DISTINCT部分一次。如果你的表在ID字段上有适当的索引,这应该会很快运行。
SELECT COUNT(1)
FROM (
SELECT DISTINCT s.Student_ID, c.CourseID, t.TeacherID
FROM student s
JOIN courses c ON s.CourseID = c.CourseID
JOIN teachers t ON c.TeacherID = t.TeacherID
WHERE t.Teacher_Age >= s.StudentAge
) a