如何获得MongoDB计数的解释?

Thi*_*ilo 15 mongodb

在MongoDB中,您可以获得有关如何执行查询的说明,并提供有趣的性能信息:

> db.people.find({ 'items' : { '$gte' : 1 } }).explain()
Run Code Online (Sandbox Code Playgroud)

我可以为"计数"(这不是查询,而是命令)获得相同的结果吗?

> db.people.count({ 'items' : { '$gte' : 1 } })
Run Code Online (Sandbox Code Playgroud)

mar*_*mor 18

Mongo 3.0引入了一种解释非游标请求的新方法:

db.my_collection.explain().count()
Run Code Online (Sandbox Code Playgroud)

请参阅:http://docs.mongodb.org/manual/reference/method/db.collection.explain/#db.collection.explain

  • 请注意,您还可以将查询传递给计数,即`db.my_collection.explain().count({ 'items' : { '$gte' : 1 } })` (2认同)

ino*_*sco 7

基于https://jira.mongodb.org/browse/SERVER-14098,新的未来版本将支持以下格式:

db.runCommand({
    explain: {
        count: 'collectionName',
        query: {
            foo: 'bar'
        }
    }
})
Run Code Online (Sandbox Code Playgroud)


Eve*_*man 3

我很确定 count(query) 是 find(query).count() 的缩写——换句话说,解释是完全相同的。除了完整的集合计数之外,没有进行任何特定的计数优化。例如,对某个范围的非索引字段运行计数与对相同范围运行 find.explain 所花费的时间完全相同。

我编写了一个名为 timeCount 的函数,它取 count 函数时间的平均值,然后显示解释输出以进行比较。

function timeCount(coll, query) {
  var n = 5;
  var total = 0;
  for(var i = 0; i < n; i++) {
    var start = new Date();
    db[coll].find(query).count();
    var end = new Date();
    total += (end - start);
    print("time[" + i + "]: " + (end - start) + "ms");
  }
  print("average time: " + (total / n));

  var explain = db[coll].find(query).explain();
  print("explain (from find): ");
  for(e in explain) {
    if(typeof explain[e] == "string" || typeof explain[e] == "number") {
      print(e + ": " + explain[e]);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

输出如下所示:

> timeCount('test',{x:{$gt:5000}});
time[0]: 1339ms
time[1]: 1280ms
time[2]: 1347ms
time[3]: 1322ms
time[4]: 1299ms
average time: 1317.4
explain (from find): 
cursor: BtreeCursor x_1_y_1
nscanned: 995062
nscannedObjects: 995062
n: 995062
millis: 1390
nYields: 0
nChunkSkips: 0
Run Code Online (Sandbox Code Playgroud)

  • 不,这没有意义。查找必须检索文档,而计数则不需要。有了索引,它应该会产生很大的影响。 (5认同)
  • @Thilo确切地说,它包括找到它们的时间(因此,扫描它们,因此 nscanned )就像 count() 所做的那样,但它实际上并没有创建游标并返回批处理。几乎不相关,因为实际返回文档通常不是最耗时的事情,但这就是它的工作原理。我同意 count().explain() 在他们优化 count() 情况时变得不同/相关。目前仅优化了完整集合 count() (在分片数据库的情况下可能会产生不一致的结果)。 (2认同)