snippetsqlMinor
This query is choking the server. How can I improve it?
Viewed 0 times
thiscanthechokingqueryimprovehowserver
Problem
Following query is hogging a lot of resources, as much as that the queries are getting locked down & CPU usage goes through the roof!
The MySQL Processes list shows that as the number of requests for the queries increases, the time to completion also increases... It reaches to a point where queries just lock down.
As per the web host, there is some problem in the query design, but I am unable to figure it out.
EXPLAIN:
DESCRIBES of the 4 tables (linked to avoid lengthy post).
EDIT 1
Based on Bohemian & a1ex07 replies, I am now using the following query. Everything is working OK but the noOfCom is being calculated wrongly for the pets that have >0 comments - it just equals to the total number of feedbacks from the petfb table for that particular pet, not the actual no of
The MySQL Processes list shows that as the number of requests for the queries increases, the time to completion also increases... It reaches to a point where queries just lock down.
As per the web host, there is some problem in the query design, but I am unable to figure it out.
SELECT DISTINCT pet.*,ownrs.id AS ownrunique, ownrs.super,
(SELECT count(*) from comments WHERE pet.id=comments.petid)
AS noOfCom,
(SELECT count(*) from petfb WHERE pet.id=petfb.petid AND (feedback=1 OR feedback=100))
AS newLikes,
(SELECT count(*) from petfb WHERE pet.id=petfb.petid AND (feedback=5 OR feedback=6))
AS newDisLikes,
ownrs.name
FROM pet, ownrs
WHERE 1=1 AND pet.ownerID=ownrs.uniqueID AND catid=21
ORDER BY date DESC LIMIT 0,10EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY pet ref catid catid 4 const 4758 Using where; Using temporary; Using filesort
1 PRIMARY ownrs eq_ref uniqueID uniqueID 52 petdb.pet.ownerID 1
4 DEPENDENT SUBQUERY petfb ref petid,feedback petid 4 petdb.pet.id 11 Using where
3 DEPENDENT SUBQUERY petfb ref petid,feedback petid 4 petdb.pet.id 11 Using where
2 DEPENDENT SUBQUERY comments ref petid petid 4 petdb.pet.id 1 Using indexDESCRIBES of the 4 tables (linked to avoid lengthy post).
EDIT 1
Based on Bohemian & a1ex07 replies, I am now using the following query. Everything is working OK but the noOfCom is being calculated wrongly for the pets that have >0 comments - it just equals to the total number of feedbacks from the petfb table for that particular pet, not the actual no of
Solution
First add the following indices:
Then try this query:
ALTER TABLE pet
ADD INDEX catid_date_index
(catid, date) ;
ALTER TABLE petfb
ADD INDEX petid_feedback_index
(petid, feedback) ;Then try this query:
SELECT pet.*
, ownrs.id AS ownrunique
, ownrs.super
, ( SELECT COUNT(*)
FROM comments
WHERE pet.id = comments.petid
) AS noOfCom
, ( SELECT MAX(comments.comDate) --- Unfortunately, you need
FROM comments --- 2 subqueries if you want
WHERE pet.id = comments.petid --- 2 results from a table
) AS lastCom --- (comments)
, ( SELECT COUNT(*)
FROM petfb
WHERE pet.id = petfb.petid
AND feedback IN (1, 100)
) AS newLikes
, ( SELECT COUNT(*)
FROM petfb
WHERE pet.id = petfb.petid
AND feedback IN (5,10)
) AS newDisLikes
, ownrs.name
FROM
( SELECT pet.*
FROM pet
WHERE catid = 21
ORDER BY `date` DESC
LIMIT 0, 10
) AS pet
INNER JOIN
ownrs
ON ownrs.uniqueID = pet.ownerID
ORDER BY p.date ;Code Snippets
ALTER TABLE pet
ADD INDEX catid_date_index
(catid, date) ;
ALTER TABLE petfb
ADD INDEX petid_feedback_index
(petid, feedback) ;SELECT pet.*
, ownrs.id AS ownrunique
, ownrs.super
, ( SELECT COUNT(*)
FROM comments
WHERE pet.id = comments.petid
) AS noOfCom
, ( SELECT MAX(comments.comDate) --- Unfortunately, you need
FROM comments --- 2 subqueries if you want
WHERE pet.id = comments.petid --- 2 results from a table
) AS lastCom --- (comments)
, ( SELECT COUNT(*)
FROM petfb
WHERE pet.id = petfb.petid
AND feedback IN (1, 100)
) AS newLikes
, ( SELECT COUNT(*)
FROM petfb
WHERE pet.id = petfb.petid
AND feedback IN (5,10)
) AS newDisLikes
, ownrs.name
FROM
( SELECT pet.*
FROM pet
WHERE catid = 21
ORDER BY `date` DESC
LIMIT 0, 10
) AS pet
INNER JOIN
ownrs
ON ownrs.uniqueID = pet.ownerID
ORDER BY p.date ;Context
StackExchange Database Administrators Q#19390, answer score: 2
Revisions (0)
No revisions yet.