Mysql:200多个游戏关卡中的每一个的排行榜

时间:2015-04-13 10:40:38

标签: mysql ranking leaderboard

我需要在mysql innodb表中存储游戏用户配置文件。但是其中可能有数百万个,配置文件记录包含200多个int32值和其他几个用于游戏内数据的值。我需要评估每个200多个整数的用户排名。 我打算这样做(例如121级):

select count(distinct(val121))  from ldbrd where 
   val121<$current_usr_val order by val121 desc

或使用帮助表{id,maxscore,minscore,count}来提高速度。

我在这里看到两个问题:

  1. 表有200多个int字段。好吗?这样的表会快吗?

  2. sql有64个索引的限制,所以我不能只为每个int字段创建一个索引,但没有索引这样的搜索会很慢。

  3. 但我很确定这项任务很常见。我的意思是有许多游戏有数百个级别 - 我认为糖果粉碎最为人所知。那人们如何解决呢?谢谢!

    ---更新

    我决定在一个表中编写二进制字段中的配置文件(一个字段中的所有这些内容),并创建另一个用于评估排名的表:{id,user_id,level_no,score,timestamp}。但如果我们有100000个用户和200个级别,我们在此表中获得20M行。 是的,所有字段都有索引,但对于具有2个内核2.4Ghz和2 Gb RAM的VDS来说太过分了。例如,查询:

    SELECT COUNT(*) FROM leaderboard WHERE level_no = 153 
       AND score < 10000 ORDER BY score DESC
    

    在19秒内完成!它太多了,而且每秒会有很多请求,每个都需要进行等级评估。

    此外,我还想过为每个级别存储一个表,也许这样会更快(至少它们会小得多)。

    另一个想法 - 生成说每个级别每小时前100名。它非常简单快速:

    SELECT score FROM leaderboard WHERE 
    level_no = 156 ORDER BY score DESC LIMIT 100
    

    但每个人都想知道他的排名。我们可以添加'rank'字段但是在20M行表中的排名评估将花费很长时间,在此查询期间服务器将忙于其他人,我想避免它。 人们通常如何做这样的事情?

    -----更新2

    表架构:

    CREATE TABLE IF NOT EXISTS `leaderboard` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `store_user_id` char(64) NOT NULL,
      `level_no` int(11) NOT NULL,
      `score` int(11) NOT NULL,
      `timestamp` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `store_user_id` (`store_user_id`),
      KEY `level_no` (`level_no`),
      KEY `score` (`score`),
      KEY `timestamp` (`timestamp`),
      KEY `lev_sc` (`level_no`,`score`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1
    /*!50100 PARTITION BY HASH (id)
    PARTITIONS 10 */ AUTO_INCREMENT=19999831 ;
    

    我最终对表格进行了分区并添加了(level_no,score)键。是19秒,现在:0,017秒。非常酷!

    仍有疑问:

    1. 我应该在生产中分区表吗?我听说人们在分区时遇到了问题。

    2. 什么是最好的选择 - 拥有500个桌子 - 每个级别一个,或者一个比我现在大500倍的桌子?每个级别的表工作速度稍快一点(0,048秒对0,072秒),但只要我有几个表就可以了。 500多个表会以相同的速度工作吗?

0 个答案:

没有答案