web-dev-qa-db-ja.com

ハッシュインデックスと昇順インデックスのMongodbパフォーマンスの違い(順序付けされていないフィールドでハッシュを使用しない理由はありますか?)

Mongodbには、 index の複数のタイプがあります。この質問では、並べ替えに使用できる 昇順(または降順)インデックス と、ドキュメントによると「主にシャードで使用される ハッシュインデックス 」に関心があります。ハッシュされたシャードキーをサポートするクラスター」( ソース )「データのより均等な分散」を保証します( ソース

エラーが発生したため、次のようなインデックスを作成できないことを知っています:db.test.ensureIndex( { "key": "hashed", "sortOrder": 1 } )

_{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "errmsg" : "exception: Currently only single field hashed index supported.",
    "code" : 16763,
    "ok" : 0
}
_

私の質問:

インデックス間:

  1. db.test.ensureIndex( { "key": 1 } )

  2. db.test.ensureIndex( { "key": "hashed" } )

クエリdb.products.find( { key: "a" } )の場合、どちらがパフォーマンスが高いですか?は、hashedキーO(1)です。


どうやって質問にたどり着いたか:

hashedでマルチキーインデックスを作成できないことを知る前に、db.test.ensureIndex( { "key": 1, "sortOrder": 1 } )の形式のインデックスを作成しました。作成中に、ハッシュインデックスの方がパフォーマンスが高いかどうか疑問に思いました。昇順(ハッシュは通常O(1)です)。 (前述のように)db.test.ensureIndex( { "key": "hashed", "sortOrder": 1 } )が許可されなかったため、キーをそのままにしました。しかし、問題は、私の心に残っているキーによる検索のハッシュインデックスがより高速であるということです。

私がインデックスを作成した状況は次のとおりです。

キーで分類されたドキュメントのソートされたリストを含むコレクションがありました。

例えば_{key: a, sortOrder: 1, ...}_、_{key: a, sortOrder: 2, ...}_、_{key: a, sortOrder: 3, ...}_、_{key: b, sortOrder: 1, ...}_、_{key: b, sortOrder: 2, ...}_、.。

分類にはkeyを使用し、ページ付けにはsortOrderを使用したため、常にkeyに1つの値を使用してフィルタリングを照会し、ドキュメントの順序にsortOrderを使用しました。

つまり、2つの可能なクエリがありました。

  • 最初のページの場合db.products.find( { key: "a" } ).limit(10).sort({"sortOrder", 1})
  • そして他のページについてはdb.products.find( { key: "a" , sortOrder: { $gt: 10 } } ).limit(10).sort({"sortOrder", 1})

この特定のシナリオでは、キーをO(1)で検索し、sortOrderをO(log(n))で検索するのが理想的でしたが、それは許可されませんでした。

28
J-Rou

クエリdb.products.find( { key: "a" } )の場合、どちらがパフォーマンスが高いですか?

フィールドkeyが両方の場合にインデックス付けされているとすると、複雑さインデックス検索自体は非常に似ています。 aの値は ハッシュ であるため、インデックスツリーに格納されます。

全体的なパフォーマンスコストを探している場合、ハッシュバージョンでは、インデックスツリーの値と一致する前にaの値をハッシュするための追加の(無視できる)コストが発生します。参照 mongo/db/index/hash_access_method.h

また、ハッシュインデックスは インデックスプレフィックス圧縮(WiredTiger) を利用できません。インデックスプレフィックスの圧縮は、カーディナリティが低いデータセット(国など)や、電話番号、社会保障コード、地理座標などの繰り返し値を持つデータセットで特に効果的です。これは、最初のフィールドが2番目のフィールドのすべての一意の値で繰り返される 複合インデックス の場合に特に効果的です。

順序付けされていないフィールドでハッシュを使用しない理由はありますか?

通常、範囲外の値をハッシュする理由はありません。シャードキーを選択するには、値の カーディナリティ頻度 、および 変化率 を考慮してください。

ハッシュインデックスは、 sharding の特定の場合に一般的に使用されます。 シャードキー 値が 単調に増加/減少 値である場合、データの分散は1つのシャードにのみ入る可能性があります。これは、ハッシュされたシャードキーが書き込みの分散を改善できる場所です。シャーディングクラスターを大幅に改善することは、マイナーなトレードオフです。 ハッシュvs遠隔シャーディング も参照してください。

ドキュメントにランダムなハッシュまたは値を挿入し、_idで生成されたハッシュの代わりにそれをシャーディングに使用する価値はありますか?

それが価値があるかどうかは、ユースケースによって異なります。カスタムハッシュ値は、ハッシュ値のクエリがカスタムハッシュコード、つまりアプリケーションを経由する必要があることを意味します。

組み込みのハッシュ関数を利用する利点は、ハッシュインデックスを使用してクエリを解決するときに、MongoDBがハッシュを自動的に計算することです。したがって、アプリケーションはハッシュを計算する必要はありません。

10
Wan Bachtiar