【问题标题】:MongoDB partial index not working as expected with countMongoDB 部分索引无法按预期使用计数
【发布时间】:2018-04-30 08:11:24
【问题描述】:

mongoDB 3.6.3 上,我创建了这个包含两百万条记录的集合:

function randInt(n) { return parseInt(Math.random()*n); }

for(var j=0; j<20; j++) {  
  print("Building op "+j);
  var bulkop=db.media.initializeOrderedBulkOp() ;
  for (var i = 0; i < 100000; ++i) {
    bulkop.insert(    
      {
        id_profile: NumberLong("222"),
        needle_id: NumberInt(randInt(2000000000)),
        visibility: NumberInt(randInt(5)),
      }
    )
  };
  print("Executing op "+j);
  bulkop.execute();
}

然后我创建这个partial index

db.media.createIndex( 
  {"id_profile": 1, "visibility": 1}, 
  {unique: false, partialFilterExpression: { "needle_id": { $exists: true } }} 
); 

然后我运行这个与部分索引完全匹配的查询:

db.media.count({$and:[
  {id_profile:NumberInt(222)},
  {visibility:NumberInt(0)},
  {needle_id:{$exists:true}}]}) 

但它很慢 :( 实际上,它的速度与我没有使用部分索引并且我需要过滤所有没有 needle_id 的文档的速度相同:

db.media.createIndex( 
  {"id_profile": 1, "visibility": 1}, 
  {unique: false} 
); 

db.media.count({$and:[
  {id_profile:NumberInt(222)},
  {visibility:NumberInt(0)},
  {needle_id:{$exists:true}}]}) 

那么它是部分索引的错误吗?我可以做些什么来加快计数?

【问题讨论】:

  • 您使用的是 mongodb 3.2 或更高版本吗?
  • 最后一个版本的 mongoDB 3.6.3
  • 会不会是因为你的收藏中没有没有needle_id的项目,所以它和其他索引的速度一样?
  • 不,它比 db.media.count({$and:[ {id_profile:NumberInt(222)}, {visibility:NumberInt(0)}]}) 慢得多
  • 嗨洛基;您能否在您的查询中尝试一些变体,看看它们中的任何一个是否有所作为?例如,您可以只向基本查询对象添加条件,而不是使用 $and。看看哪些查询使用部分索引而哪些不使用会很有趣。

标签: mongodb mongodb-query mongodb-indexes


【解决方案1】:

我调查这个问题已经有一段时间了,似乎对部分索引运行计数查询并不能避免遍历索引的所有文档。

在大型集合上创建索引时,运行基于索引的计数查询会在几毫秒内完成。它实际上是在计算所提供值的索引大小。

查看此类查询的执行计划时,我们可以单独注意到“IDX_SCAN”阶段,它代表索引扫描。 (扫描请求边界上的索引并计算其中包含的文档数)

但是当使用部分索引时,mongo 实现的计数功能似乎不是在进行索引扫描,而是在文档上运行,就像我们运行修改查询一样。然后最终返回文档的总量.

这可以通过查看此类查询的执行计划来证明,并看到它显示阶段是“FETCH”,而不是“IDX_SCAN”,而是使用索引获取,所以如果索引是根本没有创建。

更完整的信息可以在这里找到:Why does the "distinct" and "count" commands happen so slowly on indexed items in MongoDB?

【讨论】:

    猜你喜欢
    • 2013-10-06
    • 2021-08-26
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多