非常慢的NOT EXISTS查询问题

时间:2014-04-21 19:11:17

标签: mysql sql

有人可以告诉我,为什么以下查询需要1.3秒才能完成,是否有任何明显的问题?

有没有办法加快查询速度?

SELECT COUNT(DISTINCT jud.rel_id) AS count_result
    FROM exp_judging AS jud
    LEFT JOIN exp_submissions AS sub ON jud.rel_id = sub.id 
    WHERE (jud.judge_id != 781 OR jud.judge_id IS NULL)
    AND jud.pre = 1
    AND sub.member_group = 5
    AND NOT EXISTS (SELECT sub2.entry_id 
                            FROM exp_judging AS jud2
                    LEFT JOIN exp_submissions AS sub2 ON jud2.rel_id = sub2.id 
                    WHERE (jud2.judge_id = 781)
                    AND jud2.pre = 1
                    AND sub2.member_group = 5
                    AND jud2.rel_id = jud.rel_id)

3 个答案:

答案 0 :(得分:1)

我已经将整个查询重新编写为1)首先,选择exp_judging.rel_id,其中没有一行使用judge_id = 781,然后2)然后,对于这些rel_id来说,计数是从exp_judging表中获取。

修改

SELECT 
    COUNT(DISTINCT jud0.rel_id)
FROM
    exp_judging AS jud0
    INNER JOIN (
        SELECT 
            jud.rel_id as rel_id,
            SUM(
                CASE jud.judge_id
                    WHEN 781 THEN 1
                    ELSE 0
                END) sum_judge_id
        FROM 
            exp_judging AS jud
            INNER JOIN exp_submissions AS sub
                ON jud.rel_id = sub.id 
        WHERE 
            jud.pre = 1
            AND sub.member_group = 5
        GROUP BY 
            jud.rel_id) judge_id_sums
        ON jud0.rel_id = judge_id_sums.rel_id 
WHERE 
    judge_id_sums.sum_judge_id = 0;

仅当exp_judging中存在exp_submissions(作为jud.rel_id)时,内部联接jud2.rel_idexp_submissions才会计入sub2.id。但是,如果您确实要计算所有jud.rel_id(即使exp_submissions中不存在),则可以使用LEFT JOIN

答案 1 :(得分:0)

您似乎想要根据某些条件计算不同的jud.rel_id

  1. jud.pre = 1
  2. sub.member_group = 5
  3. 该组不包含法官781
  4. 回答一些问题,例如“有多少人”,“第5组中的法官”之前从未向法官781提交过申请?如果是这样,可能有一种更简单的方法来编写查询。

    在任何情况下,您的查询都被重写,以便我可以阅读:

    SELECT COUNT(DISTINCT jud.rel_id) AS count_result
    FROM exp_judging jud LEFT JOIN
         exp_submissions sub
         ON jud.rel_id = sub.id 
    WHERE (jud.judge_id != 781 OR jud.judge_id IS NULL) AND
          jud.pre = 1 AND
          sub.member_group = 5 AND
          NOT EXISTS (SELECT sub2.entry_id 
                      FROM exp_judging jud2 LEFT JOIN
                           exp_submissions sub2
                           ON jud2.rel_id = sub2.id 
                      WHERE jud2.judge_id = 781 AND
                            jud2.pre = 1 AND
                            sub2.member_group = 5 AND
                            jud2.rel_id = jud.rel_id
                     )
    

    您希望使用索引来加速查询。我对此查询的索引的最佳猜测是:

    exp_judging(judge_id, pre, rel_id)
    exp_submissions(id, member_group)
    

答案 2 :(得分:-2)

尝试使用INNER JOIN

INNER JOIN exp_submissions AS sub ON jud.rel_id = sub.id