Reputation: 5438
One of our websites has a table with about 60'000 records in it. Recently we noticed the page was timing out and could only be resolved by setting the memory limit to -1. This allowed the page to load but it was very slow. Furthermore I did not believe this was the correct way to resolve the problem, as obviously it indicates something is not quite right.
I managed to output the query that the page was running:
SELECT u.*,
(SELECT COUNT(*) FROM enquiry e WHERE e.user_id = u.id AND e.deleted = 0 AND e.time_started != 0) AS opened_count,
(SELECT COUNT(*) FROM enquiry e WHERE e.user_id = u.id AND e.deleted = 0 AND e.confirmed = 1 AND e.time_started != 0) AS confirmed_count,
(SELECT COUNT(*) FROM enquiry e WHERE e.user_id = u.id AND e.deleted = 0 AND e.call_back = 1 AND e.time_started != 0) AS call_back_count
FROM user u
WHERE u.active = 1 AND u.deleted = 0
ORDER BY u.username
I ran this query in phpMyAdmin and it takes over 30 seconds to return the results.
I feel the query needs optimising in some way but I'm struggling to work out how. I'm guessing I need to use a JOIN of some sort?
Upvotes: 0
Views: 2760
Reputation: 360562
You're really running >180,000 queries, since each of those 3 subqueries will be run once for every row in the user table.
You could try simplifying into a standard join with some groups, e.g.
SELECT user.*,
COUNT(enq.id) AS opened_count
SUM(e.confirmed = 1) AS confirmed_count
SUM(e.call_back = 1) AS call_back_count
FROM user
LEFT JOIN enquiry ON enquiry.user_id = user.id
WHERE user.active = 1 and user.deleted AND enquiry.deleted = 0
GROUP BY user.id
Upvotes: 7