MySQL排名查询和LEFT JOIN

标签 mysql sql join left-join ranking

我有一个用户和属于用户的facebook_accounts数据库。用户根据相对于其他用户拥有的积分数进行“排名”:这是通过嵌入的 SELECT 语句来完成的,该语句计算所有比该用户拥有更多积分的用户。

数据库有大约 10k 用户。以下 SQL 查询需要 MySQL 约 0.16 秒才能完成:

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 语句完全分开。

有什么建议吗?

最佳答案

我的猜测是,原始查询首先进行排序,并且仅执行排名 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

关于MySQL排名查询和LEFT JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15035467/

相关文章:

java - JDBC 连接和测试错误

php - MySQL PHP 分页 - 我的搜索有效,但分页无效

sql - Oracle:从字符串中删除前4个字符

mysql - 将 JOIN 添加到 SQL 查询

mysql - 带连接的 SQL 查询 group_concat

mysql - 使用大小写更改值

MYSQL:当某些字段未填写时查看唯一行结果

javascript - mysql在报告时间之间工作时间不方便

mysql - 在具有多个记录的连接表中搜索

带有 COUNT ON LEFT JOIN 的 MySQL 查询