Reputation: 1606
Can anyone tell me if there are any obvious issues as to why the following query is taking 1.3seconds to complete?
Is there a way I can speed this query up?
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)
Upvotes: 2
Views: 579
Reputation: 1269773
You seem to want to count the distinct jud.rel_id
subject to some conditions:
jud.pre = 1
sub.member_group = 5
Answering some question like "How many "pre" judges in group 5 have never had a submission with judge 781?". If so, there might be an easier way to write the query.
In any case, your query, rewritten so I can read it is:
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
)
You want to use indexes to speed the query. My best guess at indexes for this query are:
exp_judging(judge_id, pre, rel_id)
exp_submissions(id, member_group)
Upvotes: 0
Reputation: 5669
I have re-written the whole query to 1) first, select exp_judging.rel_id's that do not have a row with judge_id=781, and 2) then, for these rel_id's the count is obtained from the exp_judging table.
EDIT:
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;
The inner join exp_judging
and exp_submissions
will count jud.rel_id
only if jud2.rel_id
exists in exp_submissions
(as sub2.id
). However, if you do want to count all jud.rel_id
(even if it does not exist in exp_submissions
), then LEFT JOIN
may be used.
Upvotes: 1