对MongoDB中的大型集合进行范围查询

时间:2013-02-05 22:52:07

标签: mongodb

我有大约4000万份文件(约10GB)的文件集。此集合中的文档相当小(约1000字节)。主要兴趣领域如下:

start_x     integer
end_x       integer

我有一个查询为给定的x值返回一行。对于x的值,集合中只能有一个匹配的行。我为此目的使用了跟随选择器:

"start_x"=>{"$lte"=>1258}, "end_x"=>{"$gte"=> 1258}

我没有获得查询的预期性能。我开始使用复合索引(start_x = 1,end_x = 1)。查询计划显示大约400K nscanned

{
  "cursor"=>"BtreeCursor start_x_1_end_x_1", 
  "nscanned"=>417801, 
  "nscannedObjects"=>1, 
  "n"=>1, 
  "millis"=>3548, 
  "nYields"=>0, 
  "nChunkSkips"=>0, 
  "isMultiKey"=>false,
  "indexOnly"=>false
} 

随后,我在start_x和end_x字段上添加了独立索引。查询计划没有显示出太大的改进。

  • 为什么indexOnly不正确,即使我有一个复合索引并且索引中的所有字段都被索引覆盖了?

  • 有没有办法优化此查询?

1 个答案:

答案 0 :(得分:0)

我最终在end_x字段上使用索引查找来解决此问题。

  • 删除了集合上的所有索引
  • end_x字段上添加了ASC索引。
  • 查询第一个匹配的行,其上限等于或高于给定值

    row = Model.where(:end_x.gte => 1258).asc(:end_x).limit(1).first
    
  • 选中以确保返回的行确实是匹配范围

    row = (row.present? and 1258.between?(row.start_x, row.end_x)) ? row : nil