量産コードでのマングースインデックス


123

and /のMongoose ドキュメントによるMongooseJSと:MongoDBNode.js

アプリケーションが起動すると、MongooseはensureIndexスキーマで定義された各インデックスを自動的に呼び出します。開発には適していますが、インデックスの作成はパフォーマンスに大きな影響を与える可能性があるため、本動作ではこの動作を無効にすることをお勧めします。autoIndexスキーマのオプションをfalseに設定して、動作を無効にします。

これは、Mongooseを最適化するためにデプロイする前にmongooseから自動インデックス作成を削除して、Mongooseにアプリケーション起動時にすべてのインデックスを移動およびチャーンするように指示することを指示しているようです。これは理にかなっているようです。

量産コードでインデックスを処理する適切な方法は何ですか?たぶん、外部スクリプトはインデックスを生成する必要がありますか?またはensureIndex、単一のアプリケーションがコレクションへの唯一のリーダー/ライターである場合、DBの書き込みが発生するたびにインデックスを継続するため、不要な場合がありますか?

編集:補足として、MongoDBはインデックス作成の方法に関する優れたドキュメントを提供していますが明示的なインデックス作成ディレクティブを実行する理由時期については提供していません。インデックスは、既存のインデックスを持つコレクションでライターアプリケーションによって自動的に最新に保つ必要があるように思えます。これは、実際には1回限りのもの(新しいインデックスが適用されるときに行われる)です。この場合、Mongoose は、通常のサーバー再起動では何もしません。ensureIndexautoIndex

回答:


133

Mongooseのドキュメントで、運用環境で無効にすることautoIndexをお勧めする理由がわかりません。インデックスが追加されると、後続のensureIndex呼び出しは単にインデックスがすでに存在することを確認してから戻ります。そのため、最初にインデックスを作成するときにのみパフォーマンスに影響し、その時点ではコレクションが空であることが多いため、とにかくインデックスの作成が迅速になります。

私の提案は、autoIndex問題が発生する特定の状況がない限り、有効のままにしておくことです。たとえば、何百万ものドキュメントがある既存のコレクションに新しいインデックスを追加し、いつ作成されるかをより細かく制御したい場合などです。


10
追加する質問があります... falseに設定するとどうなりますか?データを挿入するとき、または明示的に作成する必要があるときに、インデックスが作成されます。これが初心者の質問でしたら申し訳ありませんが、答えていただければ本当に助かります。
サランシュモハパトラ2013

5
@SaranshMohapatra autoIndexがfalseの場合、インデックスを作成するには、モデルでsureIndexesを呼び出す必要があります。
JohnnyHK 2013年

それを毎回呼び出すか、モデルを定義するときに1回だけ呼び出すか
サランシュモハパトラ2013

モデルを定義(コンパイル)するときの@SaranshMohapatra。私は最初にアプリを起動したときにそれを行います。スキーマを変更した場合に備えて、すべてのインデックスを削除して再作成することは難しい考えです。
モス

3
@JohnnyHKほぼ2016年になった今でも、あなたの答えに同意しますか?
Alexander Mills

41

私は受け入れられた回答に同意しますがMongoDBのマニュアルによれば、これは運用サーバーにインデックスを追加する方法としては推奨されないことに注意してください。

アプリケーションにEnsureIndex()オペレーションが含まれていて、他の操作上の懸念のためにインデックスが存在しない場合、インデックスの構築はデータベースのパフォーマンスに深刻な影響を与える可能性があります。

パフォーマンスの問題を回避するには、アプリケーションが起動時にgetIndexes()メソッドまたはドライバーの同等のメソッドを使用してインデックスをチェックし、適切なインデックスが存在しない場合は終了することを確認してください。指定されたメンテナンスウィンドウ中に、別のアプリケーションコードを使用して本番インスタンスで常にインデックスを構築します。

もちろん、それは実際にアプリケーションがどのように構造化およびデプロイされるかに依存します。たとえば、Herokuにデプロイしていて、Herokuのプリブート機能を使用していない場合は、起動時にアプリケーションがリクエストをまったく処理していない可能性が高いため、その時点でインデックスを作成しても安全です。

これに加えて、受け入れられた答えから:

そのため、最初にインデックスを作成するときにのみパフォーマンスに影響し、その時点ではコレクションが空であることが多いため、とにかくインデックスの作成が迅速になります。

データモデルとクエリを初めて作成することに成功した場合は、これで問題ありません。ただし、アプリに新しい機能を追加する場合、インデックスのないプロパティで新しいDBクエリを使用すると、多くの既存のドキュメントを含むコレクションにインデックスを追加することがよくあります。

これは、インデックスの追加に注意する必要があり、そうすることによるパフォーマンスへの影響を慎重に検討する必要があるときです。たとえば、バックグラウンドでインデックスを作成できます

db.ensureIndex({ name: 1 }, { background: true });

3
わかりましたので、コレクションごとにすべてのEnsureIndexコールバックが発生するまで、サーバーを起動するだけで済みます。
Alexander Mills

@AlexMillsどのようにしてそれを確実にしますか?
lonelymo 2016年

async.each(Object.keys(models)、function(key、c​​b){models [key] .ensureIndexes(cb)}、cb)
Alexander Mills

各マングースモデルでEnsureIndexesを呼び出し、すべてが完了するのを待ってから、サーバーを起動します。サーバーを起動する前に、db接続が発生するのを待つこともお勧めします
Alexander Mills

2
ensureIndexもうありません。ありますcreateIndex代わりに。私は正しいですか?
ジャックブランク

1

次のブロックコードを使用して、プロダクションモードを処理します。

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.