【问题标题】:MongoDB data receive is too slowMongoDB数据接收太慢
【发布时间】:2023-03-25 10:27:01
【问题描述】:

我有包含大量字段的文档(每个文档有 7500 个字段) 但字段值是简单数据(仅限数字),当我尝试查询 Collection 时效果很好(我查看 mongo profiler 并正确使用索引) 但是迭代游标(接收数据)需要很长时间 结果文件的数量约为 450,但收到所有文件大约需要 2 分钟 我已经将 mongoDB 版本更新到最后一个版本,还更新了 MongoDB 驱动程序(用于 .NET),重新创建索引但没有任何帮助

P.S 连接并不慢(BD 服务器在我的本地网络中 - 100Base-T/Fast Ethernet) 查询代码示例如下

        var builder = Builders<BsonDocument>.Filter;

        var filter = builder.Eq("OrgID", orgID);
        filter = filter & builder.Eq("DateDeleted", (DateTime?)null);

        var collection = GetCollection("NameOfCollection");
        var result = collection.Find(filter);

        using (var cursor = result.ToCursor())
        {
            while (cursor.MoveNext())
            {
                var batch = cursor.Current;
                foreach (var document in batch)
                {
                    yield return document;
                }
            }
        }

我分别为这些字段建立了索引,并且在一个索引中也有两个字段的复合索引

它适用于文档更多但字段更少的集合(每个文档中约 20 个字段)

【问题讨论】:

  • 也许您可以向我们展示集合中的索引、模型(如果您不使用BsonDocument)以及您用于执行查询的代码?
  • 如果分析器报告快速生成数据,但您的应用程序检索它的时间过长,这确实表明您的连接速度非常慢,或者您的代码可以改进。
  • 无连接不慢(数据库服务器在我的本地网100Base快速以太网中)代码示例如下 var filter = builder.Eq("OrgID", orgID); filter = filter & builder.Eq("DateDeleted", (DateTime?)null); var collection = GetCollection([nameOfCollection]); result = collection.Find(filter) using (var cursor = result.ToCursor()) { while (cursor.MoveNext()) { ...... } }
  • 你应该分享一些真实的文档示例,以便人们可以尝试复制
  • 您可以创建 6000 个文档(包含 7500 个字段,每个字段名称的长度约为 80)将该文档插入集合中,然后尝试查找其中的一些 :)(例如,我的文档中的字段名称看起来像“dataContent_form01_tabCtrl05_tabPg10_group01_group03_table1000_tbx_col_12_row_30”,还有一些“系统”字段,如 DateCreated (DateTime)、DateDeleted (DateTime)、OrganizationID (Guid)、StatusID (Guid) 等)

标签: c# mongodb mongodb-.net-driver


【解决方案1】:

为什么要使用光标?我的理解是单独获取每条记录。我敢打赌,如果您通过 ToList() 进行迭代,您会获得更好的性能,因为它会在一次调用中获取所有数据。

Foreach(var batch in collection.Find(filter).ToList()){
    // your other code here
}

此外,您正在生成结果,这意味着它嵌套在 IEnumerable 中,并且您在这些检索调用之间所做的任何事情都可能会减慢该过程,但是您将代码省略了,所以很难说。

【讨论】:

  • 因为 ToList() 是“内存泄漏”,看看“yield return”是如何工作的,你就会明白为什么:)
  • 我想让你向我解释一下 ToList() 是如何导致内存泄漏的。但是,如果您想跳过 ToList() 以不迭代列表两次并将分配推迟到执行时间,您可以跳过 Find(filter).ToList() 并仅迭代 Find(filter)。对于遇到问题但并不真正知道发生了什么的人来说,你的回答有点自鸣得意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 2020-06-25
  • 1970-01-01
相关资源
最近更新 更多