【问题标题】:MongoDB performance problems in Unity GameUnity Game 中的 MongoDB 性能问题
【发布时间】:2016-07-27 09:10:34
【问题描述】:

我们决定在游戏中使用 mongo db 作为实时数据库,但搜索结果的性能无法接受。这些是包含 15.000 个文档和 17 个字段(字符串、int、float)的测试结果

   // 14000 ms 
    MongoUrl url = new MongoUrl("url-adress");
    MongoClient client = new MongoClient(url);
    var server = client.GetServer();
    var db = server.GetDatabase("myDatabase");
    var collection = db.GetCollection<PlayerFields>("Player");

    var ranks = collection.FindAll().AsQueryable().OrderByDescending(p=>p.Score).ToList().FindIndex(FindPlayer).Count();

这个是最差的。 //.ToList() 用于测试目的。不要在生产代码中使用。

第二次测试

        //9000 ms
        var ranks = collection.FindAll().AsQueryable().Where(p=>p.Score < PlayerInfos.Score).Count();

第三次测试

//2000 ms
var qq = Query. GT("Kupa", player.Score);
    var ranks = collection.Find( qq ).Where(pa=>(pa.Win + pa.Lose + pa.Draw) != 0 );

有没有其他方法可以使用 C# .Net 2.0 在 mongo 中进行快速搜索。我们想根据用户的得分得到玩家的排名并给他们排名。

【问题讨论】:

  • 我不擅长这部分关于 DB 的知识,但也许使用可以为您提供此信息的 API?因此,您只需调用一个页面,服务器就会获取该页面。
  • 你能提供你的收藏索引吗?它可能有助于诊断问题
  • 只有 1 个索引,即 ObjectId 字段。
  • 嘿,如果可能的话,尝试使用 redis 来满足您的要求,因为它更适合您的要求,我建议它作为替代方案,我建议它除了加快处理速度
  • @abhi 感谢您的建议。我会看的。

标签: c# mongodb performance linq unity3d


【解决方案1】:

需要注意的是,我已经有几年没有成为 .NET 开发人员了,所以如果 c# 驱动程序有问题,我无法评论,但我对 Mongo 有很好的了解所以希望我能帮上忙……

索引

索引将在这里为您提供很多帮助。当您对未编入索引的字段进行排序和过滤时,这只会在数据库变大时给您带来问题。

索引是特定于方向的(升序/降序)。这意味着您的“分数”字段应按降序索引:

db.player.ensureIndex({'Score': -1}) // -1 indicating descending

查询

此外,Mongo 真的很棒(在我看来),而且看起来你并没有使用它来发挥它的最大能力。

您的第一个电话:

var ranks = collection.FindAll().AsQueryable().OrderByDescending(p=>p.Score).ToList().FindIndex(FindPlayer).Count();

看来(这是我的 .NET 知识可能让我失望的地方)您正在检索整个集合 ToList(),然后在内存中过滤它 (FindPlayer predicate) 以检索数据子集。我相信这会将整个光标(15.000 个文档)评估到您的应用程序的内存中。

您应该更新您的查询,以便 Mongo 完成工作,而不是您的应用程序。

鉴于您的其他查询正在过滤 Score,如上所述添加索引应该会大大提高这些其他查询的性能

分析

如果您希望在从 mongo cli 运行时进行的调用按预期运行,则可能是驱动程序进行的查询略有不同。

在 mongo CLI 中,您首先需要设置分析:

db.setProfilingLevel(2)

然后您可以查询配置文件集合以查看实际进行了哪些查询:

db.system.profile.find().limit(5).sort({ts: -1}).pretty()

这将显示最近的 5 次通话。

【讨论】:

  • 一旦你调用 .ToList() 它就会评估内存中的任何延迟加载项,所以我认为你的假设是正确的
  • @justcompile 是的,你是对的。我们不在生产代码中使用 .ToList() ,它仅用于测试目的。创建索引来评分后,我会用第三种方式调用相同的查询吗?
  • 我只是创建索引并尝试查找这样的查询 var pla = Query.EQ("UserID", PlayerInfos.userID); PlayerFields rPlayer = playerData.PlayerInfo.Find(new QueryDocument("UserID", PlayerInfos.userID)).First();但它兴奋了 5000 毫秒。我不明白 mongodb 发生了什么。这些返回时间很慢!!
  • 您是否尝试过直接对 mongo 运行查询?如果您可以使用游标上的“解释”方法来调试调用,以了解您的查询是如何执行的。例如 db.player.find({userid: 123}).explain(true) 它会告诉您是否正在使用索引以及其他有用的东西
  • @justcompile 当我尝试getIndex时,成功返回我之前创建的索引。但在解释日志中 indexFilterSet: false。在 mongo 中,它自己一切正常......
猜你喜欢
  • 1970-01-01
  • 2021-08-07
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
  • 2019-10-16
  • 2012-11-07
  • 2011-06-30
  • 2012-08-18
相关资源
最近更新 更多