2013-02-05 33 views
1

我有大约4000万个文档(〜10GB)的文档集合。这个集合中的文档相当小(约1000字节)。主要感兴趣的领域如下:MongoDB中的大型集合的范围查询

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不是真的,即使我有一个复合索引和查询中使用的所有字段被索引覆盖?

  • 有没有一种方法来优化此查询?

回答

0

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

  • 掉在了收集
  • 增加了ASC指数end_x领域的所有指标。
  • 查询的第一个匹配行与顶部结合等于或给定值以上

    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