【问题标题】:MongoDB query optimization for large documents - dataset - query stuck针对大型文档的 MongoDB 查询优化 - 数据集 - 查询卡住
【发布时间】:2015-02-22 16:31:21
【问题描述】:

我想从 MongoDB 专家那里得到一个意见,什么 mongodb 查询优化/功能选项,我可以申请使读取查询更快,以便一次性提供如此大的文档(数据集)集合(查找查询)。

可能是 mongodb 社区中的某个人遇到了类似的问题,他们有更好的想法来解决同样的问题。

我正在使用 MongoDB2.6

要求是在一个查询中获取所有记录,因为这些文档填充在 excel 工作表中,供用户下载 excel 中的数据。

我有大量用户集合,用户集合中有 2000000 个文档。

用户集合字段:

{
_id:  ObjectId("54866f133345a61b6b9a701"),
appId: "20fabc6",
firstName: "FN",
lastName: "LN",
email: "ln@1.com",
userType: "I",
active: "true",
lastUpdatedBy: "TN",
lastUpdatedDate: ISODate("2013-01-24T05:00:00Z"),  
createdTime: ISODate("2011-01-24T05:00:00Z"),

}

我有一个查找查询,该查询目前正在从用户集合中获取 900000 个文档。在获取这么多文档时,查询似乎卡住了。

下面是查找查询:

db.test.User.find({"appId": "20fabc6"}).sort({"appId" : 1});

查询功能:

List<Users> findByAppId(Object[] appIds) {
Query query = new Query();
query.addCriteria(Criteria.where("appId").in(appIds));
return mongoTemplate.find(query, Users.class); 
}

我已经在上面的 appId 字段上放置了索引,但查询时间仍然太长。

我对查询进行了计数,我可以看到与 appId 匹配的上述查找查询的 900000 条记录

db.test.User.find({"appId": "20fabc6"}).count();
900000

以下是一些选项,我能想到的可以减少文档量:

1) 添加更多字段来过滤记录 - 这仍然是大量

db.test.User.find({"appId": "20fabc6"}, "active": "true").count();
700000

2) 使用 mongodb 限制操作限制范围查询的记录数 - 这将影响我们将所有用户数据一次性下载到 Excel 工作表中的第一个要求。

如果我们必须执行上述查找查询并一次性获取那么多文档 (900000),那么使用光标进行聚合会有所帮助还是集群中的分片会有所帮助?

如果您能提供任何帮助或解决问题的建议,我将不胜感激。

谢谢。

【问题讨论】:

  • 你有关于“appId”的索引吗?您是否需要在excel中显示所有列?目前获取记录需要多少时间?
  • 是的,我确实有关于 appId 的索引。我查看了查询计划,mongodb 在 1774 毫秒内返回查询响应的速度非常快,对于集合中的 > 900000 个文档。我还在应用程序端使用 Spring-Data-MongoDB 框架从 MongoDB 访问数据,我认为我的查询可能存在问题,因为 Spring MongoTemplate 如何访问数据。我将通过在 Spring-Data-MongoDB 查询检索上添加一些断点来在应用程序端进行更多调试以获取更多统计信息。我会让每个人都知道结果。谢谢
  • db.test.User.find({"appId": "20fabc6"}).sort({"appId" : 1}); 当您在appId 上有一个升序索引时,不需要 sort() 链。删除sort 链并简单地运行db.test.User.find({"appId": "20fabc6"})。将数据存储在 Shards 中并将 appId 设为 shard key,然后使用 $match 阶段或简单的 find 聚合结果。
  • @BatScream - 感谢您的回复。根据 MongoDB 文档,对索引进行排序的性能更好 - docs.mongodb.org/manual/tutorial/sort-results-with-indexes 但是我已经检查了查询计划,如果没有排序,则在返回结果时会在毫秒内有更好的性能。所以,我暂时不用排序。

标签: mongodb pymongo mongodb-query spring-data-mongodb mongodb-java


【解决方案1】:

您的 sort() 是不必要的,因为您试图仅查找 appId 为 20fabc6 的文档,那么为什么要按相同的 appId 排序,因为它对于返回的所有记录都是相同的?

在 appId 字段上创建索引

db.test.User.ensureIndex({"appId":1})

您的查询应该只扫描 900000 个文档。您可以使用 .explain() 方法在您的查找结果中仔细检查性能元数据。

db.test.User.find({"appId": "20fabc6"}).explain()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-15
    • 2017-09-18
    • 2017-12-11
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多