次选择替代方案

时间:2013-01-31 00:27:17

标签: mysql performance subquery

请查看此查询:

SELECT
    (SELECT COUNT(id) FROM result WHERE `mterm1` > r.mterm1 AND lesson_id = r.lesson_id) + 1 AS `pos_mt1_school`,
    (SELECT COUNT(id) FROM result WHERE `mterm1` > r.mterm1 AND lesson_id = r.lesson_id AND class_id = r.class_id) + 1 AS `pos_mt1_class`,

    (SELECT COUNT(id) FROM result WHERE `term1` > r.term1 AND lesson_id = r.lesson_id) + 1 AS `pos_t1_school`,
    (SELECT COUNT(id) FROM result WHERE `term1` > r.term1 AND lesson_id = r.lesson_id AND class_id = r.class_id) + 1 AS `pos_t1_class`,

    (SELECT COUNT(id) FROM result WHERE `mterm2` > r.mterm2 AND lesson_id = r.lesson_id) + 1 AS `pos_mt2_school`,
    (SELECT COUNT(id) FROM result WHERE `mterm2` > r.mterm2 AND lesson_id = r.lesson_id AND class_id = r.class_id) + 1 AS `pos_mt2_class`,

    (SELECT COUNT(id) FROM result WHERE `term2` > r.term2 AND lesson_id = r.lesson_id) + 1 AS `pos_t2_school`,
    (SELECT COUNT(id) FROM result WHERE `term2` > r.term2 AND lesson_id = r.lesson_id AND class_id = r.class_id) + 1 AS `pos_t2_class`,

    r.*, student.* FROM result r

LEFT JOIN lessons lesson ON r.lesson_id = lesson.id
LEFT JOIN students student ON r.student_id = student.id
LEFT JOIN classes class ON student.class_id = class.id

WHERE student.id = 217 ORDER BY lesson.id ASC

我想展示学生考试成绩。因此,首先从表格result中选择他的结果(考试成绩),然后加入lessons以显示课程名称,最后计算他的班级和学校每节课的学生位置。 (根据他的考试成绩)

该查询工作正常,但执行大约需要2秒。 (表现问题)

该查询是否有任何优化? (以及其子选择查询的替代方案)

1 个答案:

答案 0 :(得分:0)

您正在子选择中进行累积计数。

我无法想到在单个查询中在MySQL中执行此操作的另一种方法。如果“>”其中一个“=”,这可以变成一个连接。但在这种情况下,这是不可能的。

您可以使用以下查询将此转换为带聚合的显式交叉连接:

SELECT sum(case when r2.mterm1  > r.mterm1 then 1 else 0 end)+1 as `pos_mt1_school`,
       sum(case when r2.mterm1 > r.mterm1 and r2.class_id = r.class_id) + 1 then 1 else 0 end) AS `pos_mt1_class`,
       . . .
    r.*, student.*
FROM result r LEFT JOIN
     lessons lesson
     ON r.lesson_id = lesson.id LEFT JOIN
     students student
     ON r.student_id = student.id LEFT JOIN
     classes class
     ON student.class_id = class.id join
     result r2
     on r.lesson_id = r2.lesson_id
WHERE student.id = 217
group by r.result_id
ORDER BY lesson.id ASC

我不确定这会比原始版本更快。顺便说一句,原始版本将通过放置两个索引来加速:结果(lesson_id,term2)和结果(less_id,class_id,term2)。