You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询指定玩家最高得分并计算排名的语句优化问题

问题解答

查询语句修改方案

你原来的语句问题是没有先提取该玩家的最高得分,同时默认按升序排序的逻辑大概率不符合常规排行榜「得分越高排名越靠前」的规则,修改后的可直接运行的代码如下:

兼容低版本MySQL(沿用FIND_IN_SET逻辑)

SELECT 
    '4c8984f3-651a-48bc-ad1a-879624380fab' AS PlayerUUID,
    max_score AS score,
    FIND_IN_SET( 
        max_score, 
        (SELECT GROUP_CONCAT(DISTINCT iGamescore ORDER BY iGamescore DESC) 
         FROM crystm_gameScoreboard) 
    ) AS `rank`
FROM (
    -- 内层先查询目标玩家的最高得分
    SELECT MAX(iGamescore) AS max_score 
    FROM crystm_gameScoreboard 
    WHERE PlayerUUID = '4c8984f3-651a-48bc-ad1a-879624380fab'
) AS t
LIMIT 1;

说明:这里加了DISTINCT去重避免相同得分重复占位,排序改为DESC实现高分靠前的排名规则,如果你业务需要低分靠前,把DESC改回ASC即可。如果你的数据量超过10万条,GROUP_CONCAT会有默认长度限制,推荐使用MySQL 8.0+支持的窗口函数写法,性能更高无长度限制:

MySQL 8.0+ 优化版(窗口函数)

WITH player_max_score AS (
    SELECT MAX(iGamescore) as max_score 
    FROM crystm_gameScoreboard 
    WHERE PlayerUUID = '4c8984f3-651a-48bc-ad1a-879624380fab'
),
score_rank AS (
    SELECT 
        iGamescore,
        DENSE_RANK() OVER(ORDER BY iGamescore DESC) as `rank`
    FROM crystm_gameScoreboard
    GROUP BY iGamescore
)
SELECT 
    '4c8984f3-651a-48bc-ad1a-879624380fab' AS PlayerUUID,
    m.max_score as score,
    r.`rank`
FROM player_max_score m
LEFT JOIN score_rank r ON m.max_score = r.iGamescore;

业务存储方案选择

两种方案各有适用场景,优缺点如下:

  • 每次新增得分记录:
    • 优势:可留存玩家所有历史战绩,支持战绩查询、多周期排行榜(周/月榜)、用户游戏行为分析、数据问题回溯等扩展需求
    • 劣势:表数据量增长快,全表查询性能会随数据量上升下降,需要额外做分表、归档或缓存优化
  • 仅更新玩家历史最高分:
    • 优势:每个玩家仅一条数据,表体积小,查询最高分和排行榜性能极高,实现逻辑简单
    • 劣势:丢失所有历史游戏数据,无法支撑需要历史记录的扩展业务,数据出错无回溯路径

建议:如果后续有扩展业务需求,优先选新增记录的方案,可以额外维护一张玩家最高分快照表(实时/定时更新)兼顾性能和扩展性;如果仅需要总排行榜功能无其他扩展需求,选更新最高分的方案更高效。

内容的提问来源于stack exchange,提问作者Lato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 04:06:08