在排行榜表中存储数据的最佳方式是什么?在排行榜表中,每一列都必须支持排序?

kr98yfug  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(342)

我目前正在使用一个外部api重新构建一个游戏的排行榜,在这个api中,游戏中的每个数据都可以被看作是一个单独的排行榜。有超过150个以上的数据,只有少数玩家拥有全部数据,大多数玩家可能会有50-100个数据。这些数据包括不同武器的使用,游戏时间,杀戮次数等。
目前的直播版本使用了一种我不喜欢的方法,但我想不出更好的解决方案。作为 ORDER BY 需要为每一个统计可用,我有一个庞大的表150+列,每列是一个统计,这个表现在有大约20万行。被索引的列可以正常工作,但我用完了索引,因为mysql总共只允许64个,而没有被索引的列的加载速度非常慢,即使在我查看数据的前50行时也是如此。
我考虑过按类别划分统计数据,并且有6个左右的表,其中的列较少,但这意味着如果有人想同时查看武器x(武器类别)和玩过的游戏(主统计类别),我必须将表连接在一起。
除了支持每个统计数据的排行榜外,还需要支持由比率创建的排行榜,最常见的是死亡/死亡、死亡/游戏、胜利/游戏。在我的实时版本中,这是受支持的,但它确实很慢,当我试图查看每场比赛(武器x/游戏)的武器x杀死排行榜时,加载前50个结果需要几秒钟,这是当两列都在同一个表中时。
当玩家数据被添加时,包含他们数据的旧行被标记为历史数据,这样排行榜查询就可以考虑实时数据,这确实提高了我的性能,因为我不必使用 MAX(column) 为玩家找到正确的值。但我确实希望以某种方式将这些历史数据保存在表中,以便人们可以查看历史排行榜。
除了每个stat都有一列的表之外,我还考虑了一个只有一列的表 stat_id 有一列叫做 count ,但是当我尝试实现它时,我意识到如果平均每个玩家有50个统计信息,并且已经有超过20万行了,那么新表将有超过100万行,需要在每个查询上加入一个join来找出统计id是什么。
我可能已经回答了我自己的问题,即每个stat都有一列的表确实是最好的选择,但我也认为,一定有一些我没有意识到的东西或其他方法,可能会提高性能,特别是当处理的球员,目前需要50秒-每列2分钟计算排行榜位置的问题。
这是“实时排行榜”(不包括历史数据)的当前排行榜查询,其中 $columnsToSelect 是列名的字符串列表,有时是列的比率,以及 $this->params 是用户可用于自定义结果集的参数对象。少于50个游戏的玩家不会存储在排行榜表中,查询也会按id排序,这样就可以找到玩家的确切位置,并且可以找到他们所在的页面。

$sql = "SELECT s.`id`, `player`, $columnsToSelect, `lastupdated`;
        FROM stats_table as s
        WHERE $orderColumn <> 0
        AND `historical` = 0
        AND `banned` = 0 " . (
            $this->params["mingames"] > 50 ? (
                "AND `gamesplayed` >= " . $this->params["mingames"] 
            ) : ""
        );

$sql .= " AND ($orderColumn, s.id) <= (?, ?)
              ORDER BY $orderColumn DESC, s.`id` DESC
              LIMIT " . $this->params["rows"];
6ju8rftf

6ju8rftf1#

mysql并不是对每一列进行排序的最佳数据库解决方案。
你看过玛丽亚德的专栏店吗?
https://www.percona.com/blog/2017/01/30/mariadb-columnstore/
如果做不到这一点,另一个解决方案是将结果限制到足以将排序(在mysql之外)推送到客户端应用程序。

相关问题