So I am in the process of optimising a SQL query. I have cleaned it up considerably but still have some work to do. See query below:
Competitions tbl:
ID, fb_share_points, tw_share_points
comp_mapper tbl:
id, referrer_user_id, user_subscription_id, has_fb_shared, has_tw_shared, competition_id
SELECT
IF (cm.has_fb_shared = 1, IFNULL(c.fb_share_points,0), 0)
+ IF (cm.has_tw_shared = 1, IFNULL(c.tw_share_points,0), 0)
+ (SELECT count(*) FROM comp_mapper as cm2
WHERE cm2.comp_id = cm.comp_id
AND cm2.referrer_user_id = us.user_id)
as shares
FROM competitions AS c
JOIN comp_mapper as cm ON cm.competition_id = c.id
JOIN user_subscription as us on cm.user_subscription_id = us.id
WHERE c.id = :id
ORDER BY shares DESC
LIMIT :limit
When a user is referred, the ID of the referring user is placed into the referrer_user_id column of the competition entrant. The subquery calculates how many competition entrants have referred other users. I am currently trying to find another way of writing this without the subquery because the query itself takes quite a while to run. If anyone has any suggestions or recommendations then please do share!
This should return an equivalent result. The difference here is that rather than a correlated subquery, we’ve got an inline view (MySQL calls it a derived table) which is aliased as
rf.It strikes me a bit odd that the query is returning a set of rows with only a single column (
shares), and no other columns. If the intent is to return a single value, there would need to be an aggregate function (i.e.SUM()) in the select list.