我有一个属于用户的用户和 facebook_accounts 数据库。用户排名"通过与其他用户相关的点数:这是通过嵌入式SELECT语句完成的,该语句对所有用户的点数比用户数更多。
该数据库拥有~10k用户。以下SQL查询需要MySQL~0.16s来实现:
SELECT
*, (SELECT (COUNT(*) + 1)
FROM users AS UserHigher
WHERE UserHigher.points > User.points
) AS rank
FROM
users AS User
ORDER BY
User.points DESC, User.created ASC
LIMIT 0, 30
但是,添加LEFT JOIN以检索用户 facebook_account 会挂起MySQL:
SELECT
*, (SELECT (COUNT(*) + 1)
FROM users AS UserHigher
WHERE UserHigher.points > User.points
) AS rank
FROM
users AS User
LEFT JOIN
facebook_accounts AS FacebookAccount
ON (FacebookAccount.user_id = User.id)
ORDER BY
User.points DESC, User.created ASC
LIMIT 0, 30
我理解用于排名用户的COUNT()选择方法效率有点低,但这是我遇到的最可靠的方法。我不明白为什么简单的LEFT JOIN会破坏一个合理的查询,当它看起来与排名SELECT语句完全分开时。
有什么建议吗?
答案 0 :(得分:1)
我的猜测是原始查询首先执行排序,只执行排名30次。第二个查询太复杂,MySQL无法检测到这种优化。
以下内容可能有所帮助:
select *
from (SELECT *, (SELECT (COUNT(*) + 1)
FROM users AS UserHigher
WHERE UserHigher.points > User.points
) AS rank
FROM users AS User
ORDER BY User.points DESC, User.created ASC
LIMIT 0, 30
) t join
facebook_accounts AS FacebookAccount
ON (FacebookAccount.user_id = User.id)
order by points desc, created asc