这是我正在尝试运行的查询:
SELECT A.*
FROM student_lesson_progress A
LEFT JOIN student_lesson_progress B
ON A.studentId = B.studentId
AND A.lessonId = B.lessonId
WHERE A.lessonStatusTypeId = 2 AND
EXISTS (SELECT * FROM student_lesson_progress WHERE B.lessonStatusTypeID = 4)
基本上我对SQL不是很熟练,但是我试图用lessonStatusTypeID = 2返回所有行,但是只有当一行有相同的studentId和lessonId且有lessonStatusTypeID = 4时才会返回。
我的最终目标一旦我确定我的查询正确,就是如果学生(studentID)在特定课程(lessonID)上达到状态(lessonStatusTypeId)4,我想删除状态为的所有行该特定课程的特定学生2,因为不再需要该数据。
我拼凑了上面的查询,它在一个小的测试数据库上运行正常,似乎正在返回所需的行。但是,当我尝试在生产数据库上运行它时,student_lesson_progress表有大约600,000行,它只运行并运行并运行,锁定数据库,将服务器CPU固定为100%,并且永远不会返回数据。
我的猜测是我的查询非常糟糕,并且可能过于复杂,我正在尝试做什么。我非常感谢任何有关此方向的正确方向的提示或推动。
答案 0 :(得分:2)
一般经验法则: 如果您正在使用子选项,那么您可能做得不对。 这并不总是例如,如果你可以避免子选择,你应该。
这应该适用于查询。您的子选择可能会扼杀您的表现。您还应索引sutdentId和lessonId,或在两列上放置复合索引。
SELECT A.*
FROM student_lesson_progress A
INNER JOIN student_lesson_progress B
ON A.studentId = B.studentId
AND A.lessonId = B.lessonId
WHERE A.lessonStatusTypeId = 2 AND B.lessonStatusTypeID = 4
答案 1 :(得分:0)
您需要使用核心子查询。但首先要确保你有正确的指数。
SELECT distinct A.*
FROM student_lesson_progress A
WHERE A.lessonStatusTypeId = 2
AND A.studentId in (
SELECT B.studentId
FROM student_lesson_progress B
WHERE B.studentId = A.studentId
And B.lessonStatusTypeId = 4);
基本上意味着,让我列出所有状态为2的学生,他们也有相应的课程,状态为4.不同的将消除重复(如果学生有超过1课程的状态4)。
希望这有效..