所以我正在优化SQL查询。我已经清理了很多,但仍有一些工作要做。请参阅以下查询:
比赛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
当引用用户时,引荐用户的ID被放入竞赛者的referrer_user_id列中。子查询计算有多少参赛者引用其他用户。我目前正试图在没有子查询的情况下找到另一种编写方法,因为查询本身需要很长时间才能运行。如果有人有任何建议或建议,请分享!
答案 0 :(得分:1)
这应该返回相同的结果。这里的区别在于,我们有一个内联视图(MySQL称之为派生表)而不是相关子查询,其别名为rf
。
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)
+ IFNULL(rf.ref_count,0) AS shares
FROM competitions c
JOIN comp_mapper cm
ON cm.competition_id = c.id
JOIN user_subscription us
ON us.id = cm.user_subscription_id
LEFT
JOIN (
SELECT cm2.referrer_user_id
, COUNT(1) AS ref_count
FROM comp_mapper cm2
WHERE cm2.comp_id = :id
GROUP BY cm2.referrer_user_id
) rf
ON rf.referrer_user_id = us.user_id
WHERE c.id = :id
ORDER BY shares DESC
LIMIT :limit
有点奇怪的是,查询返回的行集只有一列(shares
),而没有其他列。如果意图是返回单个值,则需要在选择列表中有一个聚合函数(即SUM()
)。