1

我有大约 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即使我有一个复合索引并且查询中使用的所有字段都被索引覆盖,为什么不正确?

  • 有没有办法优化这个查询?

4

1 回答 1

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
    
于 2013-02-06T00:14:37.950 回答