【问题标题】:Mysql - is there a better way to run subqueries with high volumes of data?Mysql - 有没有更好的方法来运行具有大量数据的子查询?
【发布时间】:2014-03-27 23:53:22
【问题描述】:

好的,所以数据库中有 3 个元素用于此查询。

Person,以 person_id 为主键,

Learners_to_classes,有自己的主键和两个外键,class_id 和 person_id

以及具有主键 class_id 的类。

Learners_to_classes 与人和班级有多对多的关系,但是两个外键一起必须是唯一的(一个人不能两次参加同一个班级。

每个班级都有自己的 course_id(用于定义班级的类型)。

learners_to_classes 中有超过 4 万条记录, 超过 36,000 条个人记录, 以及大约 1,300 条记录。

我想要做的,是计算完成了一种课程的人,而不是其他人。

SELECT count(distinct ltc.person_id) AS participants,
       classes.classcode as classcode,
       DATE_FORMAT(classes.course_start_date, '%Y') AS YEARPeriod
FROM learners_to_classes AS ltc
INNER JOIN classes ON ltc.class_id = classes.class_id
WHERE classes.deleted=0
AND classes.course_id=1 
AND NOT EXISTS (SELECT *
                FROM learners_to_classes AS o
                INNER JOIN classes AS c ON o.class_id=c.class_id
                WHERE (c.course_id=2 OR c.course_id=4)
                AND o.person_id=ltc.person_id)
GROUP BY YEAR(classes.course_start_date), classcode

这个查询也需要很长时间,我希望有一种更有效的方式来获取信息。

【问题讨论】:

    标签: mysql performance subquery processing-efficiency


    【解决方案1】:

    大概,您想要参加过课程 1 但没有参加过课程 4 的人。您可以使用聚合查询和 having 子句来做到这一点。以下查询返回上过一门课但未上过另一门课的学习者:

    SELECT ltc.person_id
    FROM learners_to_classes AS ltc INNER JOIN
         classes c
         ON ltc.class_id = c.class_id
    WHERE c.deleted = 0
    GROUP BY ltc.person_id
    HAVING sum(c.course_id = 1) = 1 and
           sum(c.course_id = 4) = 0;
    

    如果您只需要这样的人数,请将其用作子查询:

    SELECT COUNT(*)
    FROM (SELECT ltc.person_id
          FROM learners_to_classes AS ltc INNER JOIN
               classes c
               ON ltc.class_id = c.class_id
          WHERE c.deleted = 0
          GROUP BY ltc.person_id
          HAVING sum(c.course_id = 1) = 1 and
                 sum(c.course_id = 4) = 0
         ) l;
    

    【讨论】:

    • 这正是我所需要的。非常非常非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多