Open4
MongoDBメモ: チューニング
MongoDB の優れたとことろ
- 1ドキュメント内に複雑な階層構造を表現したデータを格納できる
explain のコツ
- db.hoge.find().expain("executionStats") を使用することで、採用されなかったクエリプランについての情報を除外して結果表示させる
-
参考
MongoDBでのスロークエリの探し方
sparse index と partial indexの関係
- 抽象レベルでいうと、 dense index と partial index とが同じレイヤーの概念。index を 張る対象のfield (ユニークなfieldを前提)の持つ全てのドキュメント(の値)を格納したindexがdense index。ドキュメントの格納を部分的に行ったのが partial index
- partial index のうち、「indexを張る対象となるfiledをそもそも持たないドキュメントは、indexから除外する」という条件でフィルタリングをしたものをsparse index と定義している (MongoDBでの定義)
- partial index の具象概念が、 sparse index
- ドメインの直積集合の部分集合としてリレーションを定義する。
- その定義を前提とし、リレーションの各カラム(field)から1つ以上を指定して、index という対応表を作成する。
- index を構成するのは、候補キーの値を持つ値fieldと、その値を持つレコードが格納されている位置を示すポインタ値を持つfieldの2つ
- 候補キーであるfieldから値全てを抜き出してindexを構成した場合が、dense index である。null が入っているレコードの扱いについては以下を考慮する
- そもそも、null が入ることを許容するfieldを対象にindex を 張るのは避けるべき。index を張るのは、順序キーの条件を満たす1次インデックスの対象fieldのみとした方がいい
- 候補キーはそもそもnullを許容しないfieldなので、候補キーに張るという戦略がよい
- null が入ることを許容するfieldにインデックスを貼る場合、ユニークインデックスは実質上張れないことになる (null という値がたった一つのレコードにのみ出現すると確定しているのであれば別だが、それはまずあり得ないだろう)
- MongoDB の sparse index はnullの扱いが厄介となる
- Mongoにおけるsparse index は、null の値を持つドキュメントも含んだ index を作成する。その上で、index を走査する際は null の値が入っているレコード をスキップして走査するので、通常の dense index よりも効率がよくなる。
- なお、そもそも index の対象field となる fieldを持たないドキュメントに対しては、index に含めないようになっている
- しかし、上述の通りnull を許容すると実質的にユニークインデックスが張れなくなるという制約がある
- そこで、 fieldを持たないドキュメントに加えて、 null の値を持つドキュメント もindexから除外するというやり方を指定できる、 partial index の方をMongo公式は推奨している
- Mongoにおけるsparse index は、null の値を持つドキュメントも含んだ index を作成する。その上で、index を走査する際は null の値が入っているレコード をスキップして走査するので、通常の dense index よりも効率がよくなる。
- そもそも、null が入ることを許容するfieldを対象にindex を 張るのは避けるべき。index を張るのは、順序キーの条件を満たす1次インデックスの対象fieldのみとした方がいい
参考
- Sparse Indexes — MongoDB Manual
https://docs.mongodb.com/manual/core/index-sparse/ - Partial Indexes — MongoDB Manual
https://docs.mongodb.com/manual/core/index-partial/#index-type-partial
sparce indexの注意点
- mongodbのsparse indexと
{$ne: null}
的なquery - podhmo's diary
https://pod.hatenablog.com/entry/2017/08/01/202248