1

私は約4000万のドキュメント(〜10GB)のドキュメントコレクションを持っています。このコレクションのドキュメントはかなり小さいです(〜1000バイト)。主な関心分野は次のとおりです。

start_x     integer
end_x       integer

xの特定の値の行を返すクエリがあります。xの値の場合、コレクションには一致する行が1つだけ存在する可能性があります。私はこの目的のために次のセレクターを使用しています:

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

クエリに対して期待されるパフォーマンスが得られません。複合インデックス(start_x = 1、end_x = 1)から始めました。クエリプランは約400Kのスキャンを示しました

{
  "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 に答える