web-dev-qa-db-ja.com

Mongodb:EnsureIndexを呼び出すタイミング?

EnsureIndexはいつ呼び出す必要がありますか?単一のレコードを挿入する前、単一のレコードを挿入した後、またはfind()を呼び出す前?

よろしく、

ジョニー

41
Johnny

私のコメントは少し誤解されているようですので、はっきりさせておきます。初めてfind()を呼び出す前のある時点で呼び出される限り、いつ呼び出すかは重要ではありません。つまり、 、それを使用する前に存在する限り、インデックスを作成するときにそれは本当に問題ではありません。

私がよく目にした一般的なパターンは、ensureIndexfind()呼び出しと同時に(および同じ場所に)コーディングすることです。 ensureIndexは、インデックスが存在するかどうかを確認し、存在しない場合は作成します。 find()を呼び出す前に、ensureindexを呼び出すと、(非常に小さいとはいえ)ある程度のオーバーヘッドがあることは間違いありません。そのため、これを行わないことが推奨されます。

コードでensureIndexを呼び出して、デプロイを簡略化し、dbとコードベースを個別に管理する必要をなくしています。展開の容易さのトレードオフは、ensureIndexへの後続の呼び出しの冗長性をバランスさせます(私にとって)。

19
Code Magician

アプリケーションの起動時に、ensureIndexを一度呼び出すことをお勧めします。

16
UpTheCreek

それは問題ではありませんが、これを行う必要があるのは一度だけです。大量のデータを空のコレクションにバッチ挿入する場合は、挿入後にインデックスを作成するのが最適ですが、それ以外の場合は問題ありません。

4
Karoly Horvath

これを行う必要があるのは1回だけです。例:

db.table.insert({foo: 'bar'});
var foo = db.table.findOne({foo: 'bar'}); // => delivered from FS, not RAM
db.table.ensureIndex({foo: 1});
var foo = db.table.findOne({foo: 'bar'}); // => delivered from RAM, not FS
db.table.insert({foo: 'foo'});
var foo = db.table.findOne({foo: 'foo'}); // => delivered from RAM, not FS
2
elslooo

通常、アプリケーションのMongoDBとの通信を管理する部分のinitブロック内にensureIndex()呼び出しを配置し​​ます。また、これらのensureIndex()呼び出しを、アプリケーションが機能するために存在しなければならないことがわかっているコレクションの存在のチェック内にラップします。このようにして、アプリケーションが特定のMongoDBインスタンスに対して初めて実行されるときに、ensureIndex()呼び出しが呼び出されるのは1回だけです。

他の開発者が誤ってそれらを変更してDB(インデックス)を変更する可能性があるので、アプリケーションコードにEnsureIndex()呼び出しを配置することに対する意見を別の場所で読んだことがありますが、コレクションの存在を確認するためにラップすると、これを防ぐのに役立ちます。

Java MongoDBドライバーの例:

DB db = mongo.getDB("databaseName");
Set<String> existingCollectionNames = db.getCollectionNames();

// init collections; ensureIndexes only if creating collection
// (let application set up the db if it's not already)
DBCollection coll = db.getCollection("collectionName");
if (!existingCollectionNames.contains("collectionName")) {
// ensure indexes...
coll.ensureIndex(BasicDBObjectBuilder.start().add("date", 1).get());
    // ...
}
1
ericsoco

数百万のレコードを持つコレクションがあり、自動インデックス作成をオフにして複数の複合インデックスを構築している場合は、最初の検索クエリのかなり前、おそらく同期して、つまり、ensureIndexesメソッドが戻った後に、ensureIndexes()を呼び出すようにする必要があります。

インデックスが作成されるモード(フォアグラウンドとバックグラウンド)では、さらに複雑になります。フォアグラウンドモードでは、インデックスの構築中にデータベース全体がロックされますが、バックグラウンドモードではデータベースにクエリを実行できます。ただし、インデックス作成のバックグラウンドモードには余分な時間がかかります。

したがって、インデックスが正常に作成されていることを確認する必要があります。 db.currentOp()を使用して、インデックスを作成している間に、ensureIndexes()の進行状況を確認できます。

1
GauravLuthra

事前にインデックスを追加する場合、挿入/更新/削除の呼び出しごとに、各インデックスも変更する必要があります。したがって、最適化の観点からは、クエリを発行する前にできるだけ長く延期する必要があります。ただし、機能的な観点からは問題ではありません。

1
jacobra