MySQL排名查询和LEFT JOIN

时间:2013-02-23 00:22:23

标签: mysql sql join left-join ranking

我有一个属于用户的用户 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语句完全分开时。

有什么建议吗?

1 个答案:

答案 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